gen_uuid_nt.c revision d1154eb460efe588eaed3d439c1caaca149fa362
1/*
2 * gen_uuid_nt.c -- Use NT api to generate uuid
3 *
4 * Written by Andrey Shedel (andreys@ns.cr.cyco.com)
5 */
6
7
8#include "config.h"
9#include "uuidP.h"
10
11#pragma warning(push,4)
12
13#pragma comment(lib, "ntdll.lib")
14
15//
16// Here is a nice example why it's not a good idea
17// to use native API in ordinary applications.
18// Number of parameters in function below was changed from 3 to 4
19// for NT5.
20//
21//
22// NTSYSAPI
23// NTSTATUS
24// NTAPI
25// NtAllocateUuids(
26//     OUT PULONG p1,
27//     OUT PULONG p2,
28//     OUT PULONG p3,
29//     OUT PUCHAR Seed // 6 bytes
30//   );
31//
32//
33
34unsigned long
35__stdcall
36NtAllocateUuids(
37   void* p1,  // 8 bytes
38   void* p2,  // 4 bytes
39   void* p3   // 4 bytes
40   );
41
42typedef
43unsigned long
44(__stdcall*
45NtAllocateUuids_2000)(
46   void* p1,  // 8 bytes
47   void* p2,  // 4 bytes
48   void* p3,  // 4 bytes
49   void* seed // 6 bytes
50   );
51
52
53
54//
55// Nice, but instead of including ntddk.h ot winnt.h
56// I should define it here because they MISSED __stdcall in those headers.
57//
58
59__declspec(dllimport)
60struct _TEB*
61__stdcall
62NtCurrentTeb(void);
63
64
65//
66// The only way to get version information from the system is to examine
67// one stored in PEB. But it's pretty dangerouse because this value could
68// be altered in image header.
69//
70
71static
72int
73Nt5(void)
74{
75	//return NtCuttentTeb()->Peb->OSMajorVersion >= 5;
76	return (int)*(int*)((char*)(int)(*(int*)((char*)NtCurrentTeb() + 0x30)) + 0xA4) >= 5;
77}
78
79
80
81
82void uuid_generate(uuid_t out)
83{
84	if(Nt5())
85	{
86		unsigned char seed[6];
87		((NtAllocateUuids_2000)NtAllocateUuids)(out, ((char*)out)+8, ((char*)out)+12, &seed[0] );
88	}
89	else
90	{
91		NtAllocateUuids(out, ((char*)out)+8, ((char*)out)+12);
92	}
93}
94