00001 /* 00002 * gen_uuid_nt.c -- Use NT api to generate uuid 00003 * 00004 * Written by Andrey Shedel (andreys@ns.cr.cyco.com) 00005 * Copyright (C) 2005, Net Integration Technologies, Inc. 00006 * 00007 * %Begin-Header% 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 1. Redistributions of source code must retain the above copyright 00012 * notice, and the entire permission notice in its entirety, 00013 * including the disclaimer of warranties. 00014 * 2. Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the distribution. 00017 * 3. The name of the author may not be used to endorse or promote 00018 * products derived from this software without specific prior 00019 * written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 00022 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 00024 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 00025 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00026 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00028 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00031 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 00032 * DAMAGE. 00033 * %End-Header% 00034 */ 00035 00036 #ifdef WIN32 00037 00038 #include "uuidP.h" 00039 00040 #pragma warning(push,4) 00041 00042 #pragma comment(lib, "ntdll.lib") 00043 00044 // 00045 // Here is a nice example why it's not a good idea 00046 // to use native API in ordinary applications. 00047 // Number of parameters in function below was changed from 3 to 4 00048 // for NT5. 00049 // 00050 // 00051 // NTSYSAPI 00052 // NTSTATUS 00053 // NTAPI 00054 // NtAllocateUuids( 00055 // OUT PULONG p1, 00056 // OUT PULONG p2, 00057 // OUT PULONG p3, 00058 // OUT PUCHAR Seed // 6 bytes 00059 // ); 00060 // 00061 // 00062 00063 unsigned long 00064 __stdcall 00065 NtAllocateUuids( 00066 void* p1, // 8 bytes 00067 void* p2, // 4 bytes 00068 void* p3 // 4 bytes 00069 ); 00070 00071 typedef 00072 unsigned long 00073 (__stdcall* 00074 NtAllocateUuids_2000)( 00075 void* p1, // 8 bytes 00076 void* p2, // 4 bytes 00077 void* p3, // 4 bytes 00078 void* seed // 6 bytes 00079 ); 00080 00081 00082 00083 // 00084 // Nice, but instead of including ntddk.h ot winnt.h 00085 // I should define it here because they MISSED __stdcall in those headers. 00086 // 00087 00088 __declspec(dllimport) 00089 struct _TEB* 00090 __stdcall 00091 NtCurrentTeb(void); 00092 00093 00094 // 00095 // The only way to get version information from the system is to examine 00096 // one stored in PEB. But it's pretty dangerouse because this value could 00097 // be altered in image header. 00098 // 00099 00100 static 00101 int 00102 Nt5(void) 00103 { 00104 //return NtCuttentTeb()->Peb->OSMajorVersion >= 5; 00105 return (int)*(int*)((char*)(int)(*(int*)((char*)NtCurrentTeb() + 0x30)) + 0xA4) >= 5; 00106 } 00107 00108 00109 00110 /* Use the native Windows UUID generation facilities. */ 00111 void uuid_generate(uuid_t out) 00112 { 00113 if(Nt5()) 00114 { 00115 unsigned char seed[6]; 00116 ((NtAllocateUuids_2000)NtAllocateUuids)(out, ((char*)out)+8, ((char*)out)+12, &seed[0] ); 00117 } 00118 else 00119 { 00120 NtAllocateUuids(out, ((char*)out)+8, ((char*)out)+12); 00121 } 00122 } 00123 00124 00125 /* The following two functions exist to provide compatibility. */ 00126 void uuid_generate_random(uuid_t out) 00127 { 00128 uuid_generate(out); 00129 } 00130 00131 void uuid_generate_time(uuid_t out) 00132 { 00133 uuid_generate(out); 00134 } 00135 00136 #endif /* WIN32 */