9 #include "wine/windef16.h"
19 #ifdef HAVE_SYS_FILE_H
20 # include <sys/file.h>
22 #include <sys/ioctl.h>
23 #ifdef HAVE_SYS_SOCKET_H
24 # include <sys/socket.h>
26 #ifdef HAVE_SYS_SOCKIO_H
27 # include <sys/sockio.h>
32 #ifdef HAVE_NETINET_IN_H
33 # include <netinet/in.h>
36 #include "debugtools.h"
38 DEFAULT_DEBUG_CHANNEL(ole
);
40 /***********************************************************************
44 * hinstDLL [I] handle to the DLL's instance
46 * lpvReserved [I] reserved, must be NULL
53 static DWORD RPCRT4_dwProcessesAttached
= 0;
56 RPCRT4_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
59 case DLL_PROCESS_ATTACH
:
60 RPCRT4_dwProcessesAttached
++;
63 case DLL_PROCESS_DETACH
:
64 RPCRT4_dwProcessesAttached
--;
71 /*************************************************************************
74 * Creates a 128bit UUID.
75 * Implemented according the DCE specification for UUID generation.
76 * Code is based upon uuid library in e2fsprogs by Theodore Ts'o.
77 * Copyright (C) 1996, 1997 Theodore Ts'o.
83 RPC_STATUS WINAPI
UuidCreate(UUID
*Uuid
)
85 static char has_init
= 0;
87 static int adjustment
= 0;
88 static struct timeval last
= {0, 0};
89 static UINT16 clock_seq
;
91 unsigned long long clock_reg
;
92 UINT clock_high
, clock_low
;
93 UINT16 temp_clock_seq
, temp_clock_mid
, temp_clock_hi_and_version
;
96 struct ifreq ifr
, *ifrp
;
102 /* Have we already tried to get the MAC address? */
105 /* BSD 4.4 defines the size of an ifreq to be
106 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
107 * However, under earlier systems, sa_len isn't present, so
108 * the size is just sizeof(struct ifreq)
112 # define max(a,b) ((a) > (b) ? (a) : (b))
114 # define ifreq_size(i) max(sizeof(struct ifreq),\
115 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
117 # define ifreq_size(i) sizeof(struct ifreq)
118 # endif /* HAVE_SA_LEN */
120 sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
122 /* if we can't open a socket, just use random numbers */
123 /* set the multicast bit to prevent conflicts with real cards */
124 a
[0] = (rand() & 0xff) | 0x80;
125 a
[1] = rand() & 0xff;
126 a
[2] = rand() & 0xff;
127 a
[3] = rand() & 0xff;
128 a
[4] = rand() & 0xff;
129 a
[5] = rand() & 0xff;
131 memset(buf
, 0, sizeof(buf
));
132 ifc
.ifc_len
= sizeof(buf
);
134 /* get the ifconf interface */
135 if (ioctl (sd
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
137 /* no ifconf, so just use random numbers */
138 /* set the multicast bit to prevent conflicts with real cards */
139 a
[0] = (rand() & 0xff) | 0x80;
140 a
[1] = rand() & 0xff;
141 a
[2] = rand() & 0xff;
142 a
[3] = rand() & 0xff;
143 a
[4] = rand() & 0xff;
144 a
[5] = rand() & 0xff;
146 /* loop through the interfaces, looking for a valid one */
148 for (i
= 0; i
< n
; i
+= ifreq_size(*ifr
) ) {
149 ifrp
= (struct ifreq
*)((char *) ifc
.ifc_buf
+i
);
150 strncpy(ifr
.ifr_name
, ifrp
->ifr_name
, IFNAMSIZ
);
151 /* try to get the address for this interface */
152 # ifdef SIOCGIFHWADDR
153 if (ioctl(sd
, SIOCGIFHWADDR
, &ifr
) < 0)
155 memcpy(a
, (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
, 6);
158 if (ioctl(sd
, SIOCGENADDR
, &ifr
) < 0)
160 memcpy(a
, (unsigned char *) ifr
.ifr_enaddr
, 6);
162 /* XXX we don't have a way of getting the hardware address */
166 # endif /* SIOCGENADDR */
167 # endif /* SIOCGIFHWADDR */
168 /* make sure it's not blank */
169 if (!a
[0] && !a
[1] && !a
[2] && !a
[3] && !a
[4] && !a
[5])
174 /* if we didn't find a valid address, make a random one */
175 /* once again, set multicast bit to avoid conflicts */
176 a
[0] = (rand() & 0xff) | 0x80;
177 a
[1] = rand() & 0xff;
178 a
[2] = rand() & 0xff;
179 a
[3] = rand() & 0xff;
180 a
[4] = rand() & 0xff;
181 a
[5] = rand() & 0xff;
188 /* no networking info, so generate a random address */
189 a
[0] = (rand() & 0xff) | 0x80;
190 a
[1] = rand() & 0xff;
191 a
[2] = rand() & 0xff;
192 a
[3] = rand() & 0xff;
193 a
[4] = rand() & 0xff;
194 a
[5] = rand() & 0xff;
195 #endif /* HAVE_NET_IF_H */
199 /* generate time element of GUID */
201 /* Assume that the gettimeofday() has microsecond granularity */
202 #define MAX_ADJUSTMENT 10
205 gettimeofday(&tv
, 0);
206 if ((last
.tv_sec
== 0) && (last
.tv_usec
== 0)) {
207 clock_seq
= ((rand() & 0xff) << 8) + (rand() & 0xff);
212 if ((tv
.tv_sec
< last
.tv_sec
) ||
213 ((tv
.tv_sec
== last
.tv_sec
) &&
214 (tv
.tv_usec
< last
.tv_usec
))) {
215 clock_seq
= (clock_seq
+1) & 0x1FFF;
217 } else if ((tv
.tv_sec
== last
.tv_sec
) &&
218 (tv
.tv_usec
== last
.tv_usec
)) {
219 if (adjustment
>= MAX_ADJUSTMENT
)
225 clock_reg
= tv
.tv_usec
*10 + adjustment
;
226 clock_reg
+= ((unsigned long long) tv
.tv_sec
)*10000000;
227 clock_reg
+= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
229 clock_high
= clock_reg
>> 32;
230 clock_low
= clock_reg
;
231 temp_clock_seq
= clock_seq
| 0x8000;
232 temp_clock_mid
= (UINT16
)clock_high
;
233 temp_clock_hi_and_version
= (clock_high
>> 16) | 0x1000;
235 /* pack the information into the GUID structure */
237 ((unsigned char*)&Uuid
->Data1
)[3] = (unsigned char)clock_low
;
239 ((unsigned char*)&Uuid
->Data1
)[2] = (unsigned char)clock_low
;
241 ((unsigned char*)&Uuid
->Data1
)[1] = (unsigned char)clock_low
;
243 ((unsigned char*)&Uuid
->Data1
)[0] = (unsigned char)clock_low
;
245 ((unsigned char*)&Uuid
->Data2
)[1] = (unsigned char)temp_clock_mid
;
246 temp_clock_mid
>>= 8;
247 ((unsigned char*)&Uuid
->Data2
)[0] = (unsigned char)temp_clock_mid
;
249 ((unsigned char*)&Uuid
->Data3
)[1] = (unsigned char)temp_clock_hi_and_version
;
250 temp_clock_hi_and_version
>>= 8;
251 ((unsigned char*)&Uuid
->Data3
)[0] = (unsigned char)temp_clock_hi_and_version
;
253 ((unsigned char*)Uuid
->Data4
)[1] = (unsigned char)temp_clock_seq
;
254 temp_clock_seq
>>= 8;
255 ((unsigned char*)Uuid
->Data4
)[0] = (unsigned char)temp_clock_seq
;
257 ((unsigned char*)Uuid
->Data4
)[2] = a
[0];
258 ((unsigned char*)Uuid
->Data4
)[3] = a
[1];
259 ((unsigned char*)Uuid
->Data4
)[4] = a
[2];
260 ((unsigned char*)Uuid
->Data4
)[5] = a
[3];
261 ((unsigned char*)Uuid
->Data4
)[6] = a
[4];
262 ((unsigned char*)Uuid
->Data4
)[7] = a
[5];
264 TRACE("%s", debugstr_guid(Uuid
));