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
34 unsigned long
35 __stdcall
36 NtAllocateUuids(
37 void* p1, // 8 bytes
38 void* p2, // 4 bytes
39 void* p3 // 4 bytes
40 );
41
42 typedef
43 unsigned long
44 (__stdcall*
45 NtAllocateUuids_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)
60 struct _TEB*
61 __stdcall
62 NtCurrentTeb(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 dangerous because this value could
68 // be altered in image header.
69 //
70
71 static
72 int
Nt5(void)73 Nt5(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
uuid_generate(uuid_t out)82 void 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