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