-1

I've found some legacy code that goes wrong, setting file attributes. It looks something like this -

flag1 = 0x0001;
flag2 = 0x0002;

DWORD flags = flag1 | flag2;

//great - flags is 3

DWORD prevValue  = 0x0010; //say

//add our new flags to prevValue
DWORD newVal = prevValue | flags;

//newVal is 19

//but now I want to remove those flags from newVal

DWORD backToPrev = newVal & !flags;

//but according to my compiler (vs2012)
//!flags is 0, it can't do the logical NOT on the DWORD

ASSERT (backToPrev); // it's 0, should be 16

Any suggestions for a fix?

Leo Chapiro
  • 13,678
  • 8
  • 61
  • 92
craker
  • 67
  • 9

2 Answers2

1

The ! operator is a logical NOT. The result of this operator is either 0 or 1. What you want is the bitwise NOT operator ~:

DWORD backToPrev = newVal & ~flags;
dbush
  • 205,898
  • 23
  • 218
  • 273
0

You can use | when specifying flags, |= to add flags and ~ to remove them.

#include <Windows.h>
#include <iostream>
using namespace std;

DWORD UpdateFlags(
    DWORD CurrentFlags,
    DWORD RemoveFlag
)
{
    return CurrentFlags & ~RemoveFlag;
}

int main()
{
    DWORD MyFlags = PROCESS_VM_OPERATION | PROCESS_VM_READ;

    MyFlags = UpdateFlags(MyFlags,
        PROCESS_VM_READ);

    getchar();
    return 0;
}

If you do this, you can easily update the flags without having to keep using & ~. Much simpler for readability. In the above example, MyFlags is assigned PROCESS_VM_OPERATION and PROCESS_VM_READ flags (so 24 total value for me), after updating the flags to remove PROCESS_VM_READ, it became 8 for the value because we removed PROCESS_VM_READ and are left only with PROCESS_VM_OPERATION.

To check for presence of flags:

BOOL IsFlagPresent(
    DWORD CurrentFlags,
    DWORD TargetFlag
)
{
    return ((CurrentFlags & TargetFlag) == TargetFlag) ?
        TRUE : FALSE;
}