Flags

Dword

Nowadays I am trying to implement something that includes lot of P/Invoke calls, and several DWORD flags are included in the calls. The DWORD is unsigned 32-bit integer and is usually represented like hexadecimal number – 0x000000ff. At first it all seemed peachy until it  turned out that the standard PowerShell converts the hexadecimal representation of number to integer (values less than 0 are possible) and not the unsigned integer (negative numbers are not possible). Let’s see an example:

Here is the maximum value of the DWORD represented in hexadecimal format 0xffffffff. I expect it to be 4294967295 (the same as the maximum value of unsigned 32-bit integer [uint32]::MaxValue) but running it in PowerShell console returns -1, a value clearly not belonging to scope of the UInt32 type.

I realized I need to do the conversion myself and found it can be done easily using static methods of the System.Convert class. In the example I specify a hexadecimal representation of the number as a string and the base of the hexadecimal number which is 16.

[Convert]::ToUInt32("0xffffffff",16)
Note: Changing the base value to 2 enables you to work with binary numbers, changing it to 8 enables you to work with octal number, changing it to 10 makes it work with decimal numbers (default).

This is easy, but inconvenient and error-prone so I created function called ConvertFrom-Dword that validates the input values for me and returns the number as unsigned integer:

function ConvertFrom-Dword
{
	[CmdletBinding()]
	param (
		[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
		[ValidatePattern("^(0x)?(0+)?[0-9|a-f]{1,8}`$")]
		[string]$Value
	)
	#0xffffffff -band 0xFFFFFFFFL is also possible
	$base = 16
	Write-Verbose "Converting DWORD value $value to decimal."
	[Convert]::ToUInt32($Value,$base)
}
ConvertFrom-Dword -Value 0xffffffff
(ConvertFrom-Dword -Value 0xffffffff).getType().fullname

4294967295
System.UInt32

This is easier but still not perfect, but for the time being it will do.

In real life we can for example take the CreateFile function documented here. By the name of the function you would probably say it is used just to create files, but it is also able to open existing file. When you perform this action you can decide if you need the file opened exclusively (lock it) or if you want to share access to the file with other processes. For that purpose there is parameter dwShareMode you can set by specifying correct “flags” (DWORD values).

The description on the linked page says:

The requested sharing mode of the file or device, which can be read, write, both, delete, all of these, or none (refer to the following table).

0
0×00000000

FILE_SHARE_DELETE
0×00000004

FILE_SHARE_READ
0×00000001

FILE_SHARE_WRITE
0×00000002

If you read carefully you probably wonder how you specify the “both” and “all of them” cases if there are no such items in the table. The solution is connecting them by the “-bor” (bit OR) operator.  If you want to share both write and read you do: 0×00000001 –bor 0×00000002. Which returns 3 or 0×00000003 in case you use this little trick.

function ConvertTo-Dword ([uint32]$Number)
{
	"0x{0:x8}" -f ($Number)
}
ConvertTo-Dword 3

0x00000003

The operation –bor did, may look like a simple adding but it is not because 1 –bor 1 = 1, instead it does operation on binary representation of the number. Look at the items in the table again. Why is 0×00000003 missing?

Now I see I need some more instruments to work easily with this type of data, back to console…

Add new TFS Service to PowerGUI.

Connecting PowerGUI to TFS Service

Recently I have come across Microsoft Team Foundation Server Service preview. The service is currently offered for free and supports both TFS and Git version control systems. So I have signed up :) The only thing that reminded to make use of it was to connect PowerGUI to the service which turned out to be quite trivial. So I will show you how to do step by step:
Some basic documentation on connecting PowerGUI to TFS is provided on the PowerGUI Wiki. To be able to connect to the TFS Service you need newer MSSCCI Provider installed. Both 32-bit and 64-bit version are available on Microsoft pages, but my PowerGUI x64 seems to detect only the 32-bit version.
When you have downloaded and installed the client you need to restart your PowerGUI editor and go to Tools > Options… > Version Control and select Team foundation Server MSSCCI provider as your current provider.

Then, in the main editor window, go to new Version Control menu and choose Get files from Version Control. New windows appears, where you can choose which provider you want to use. You probably have none there yet so you need to add one by clicking Servers… > Add… This will get you to this menu:
Add new TFS Service to PowerGUI.
Here you have to specify URL to your TFSS account followed by “/DefaultCollection”. Click OK and you should be prompted to login to your Microsoft account:

Logging in takes few moments and then you are hopefully presented with this window:

Just click Cancel to return to the selector:

Click OK here and you are good to go.

In the next step you need to choose local folder to store the data and also choose server path to the project you work on.

Next you need to choose file you will edit, I have chosen to name it hello.ps1.


If you are yet to create one go to your browser, navigate to your TFSS web page and create new Team project.

Now you have your file opened and you can CheckOut, make your changes and CheckIn.