/* * gen_uuid_nt.c -- Use NT api to generate uuid * * Written by Andrey Shedel (andreys@ns.cr.cyco.com) */ #include "uuidP.h" #pragma warning(push,4) #pragma comment(lib, "ntdll.lib") // // Here is a nice example why it's not a good idea // to use native API in ordinary applications. // Number of parameters in function below was changed from 3 to 4 // for NT5. // // // NTSYSAPI // NTSTATUS // NTAPI // NtAllocateUuids( // OUT PULONG p1, // OUT PULONG p2, // OUT PULONG p3, // OUT PUCHAR Seed // 6 bytes // ); // // unsigned long __stdcall NtAllocateUuids( void* p1, // 8 bytes void* p2, // 4 bytes void* p3 // 4 bytes ); typedef unsigned long (__stdcall* NtAllocateUuids_2000)( void* p1, // 8 bytes void* p2, // 4 bytes void* p3, // 4 bytes void* seed // 6 bytes ); // // Nice, but instead of including ntddk.h ot winnt.h // I should define it here because they MISSED __stdcall in those headers. // __declspec(dllimport) struct _TEB* __stdcall NtCurrentTeb(void); // // The only way to get version information from the system is to examine // one stored in PEB. But it's pretty dangerouse because this value could // be altered in image header. // static int Nt5(void) { //return NtCuttentTeb()->Peb->OSMajorVersion >= 5; return (int)*(int*)((char*)(int)(*(int*)((char*)NtCurrentTeb() + 0x30)) + 0xA4) >= 5; } void uuid_generate(uuid_t out) { if(Nt5()) { unsigned char seed[6]; ((NtAllocateUuids_2000)NtAllocateUuids)(out, ((char*)out)+8, ((char*)out)+12, &seed[0] ); } else { NtAllocateUuids(out, ((char*)out)+8, ((char*)out)+12); } }