18 #ifdef HAVE_SYS_FILE_H
19 # include <sys/file.h>
21 #include <sys/ioctl.h>
22 #ifdef HAVE_SYS_SOCKET_H
23 # include <sys/socket.h>
25 #ifdef HAVE_SYS_SOCKIO_H
26 # include <sys/sockio.h>
31 #ifdef HAVE_NETINET_IN_H
32 # include <netinet/in.h>
35 #include "debugtools.h"
37 DEFAULT_DEBUG_CHANNEL(ole
);
39 /***********************************************************************
43 * hinstDLL [I] handle to the DLL's instance
45 * lpvReserved [I] reserved, must be NULL
52 static DWORD RPCRT4_dwProcessesAttached
= 0;
55 RPCRT4_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
58 case DLL_PROCESS_ATTACH
:
59 RPCRT4_dwProcessesAttached
++;
62 case DLL_PROCESS_DETACH
:
63 RPCRT4_dwProcessesAttached
--;
70 /*************************************************************************
73 * Creates a 128bit UUID.
74 * Implemented according the DCE specification for UUID generation.
75 * Code is based upon uuid library in e2fsprogs by Theodore Ts'o.
76 * Copyright (C) 1996, 1997 Theodore Ts'o.
82 RPC_STATUS RPC_ENTRY
UuidCreate(UUID
*Uuid
)
84 static char has_init
= 0;
86 static int adjustment
= 0;
87 static struct timeval last
= {0, 0};
88 static UINT16 clock_seq
;
90 unsigned long long clock_reg
;
91 UINT clock_high
, clock_low
;
92 UINT16 temp_clock_seq
, temp_clock_mid
, temp_clock_hi_and_version
;
95 struct ifreq ifr
, *ifrp
;
101 /* Have we already tried to get the MAC address? */
104 /* BSD 4.4 defines the size of an ifreq to be
105 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
106 * However, under earlier systems, sa_len isn't present, so
107 * the size is just sizeof(struct ifreq)
111 # define max(a,b) ((a) > (b) ? (a) : (b))
113 # define ifreq_size(i) max(sizeof(struct ifreq),\
114 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
116 # define ifreq_size(i) sizeof(struct ifreq)
117 # endif /* HAVE_SA_LEN */
119 sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
121 /* if we can't open a socket, just use random numbers */
122 /* set the multicast bit to prevent conflicts with real cards */
123 a
[0] = (rand() & 0xff) | 0x80;
124 a
[1] = rand() & 0xff;
125 a
[2] = rand() & 0xff;
126 a
[3] = rand() & 0xff;
127 a
[4] = rand() & 0xff;
128 a
[5] = rand() & 0xff;
130 memset(buf
, 0, sizeof(buf
));
131 ifc
.ifc_len
= sizeof(buf
);
133 /* get the ifconf interface */
134 if (ioctl (sd
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
136 /* no ifconf, so just use random numbers */
137 /* set the multicast bit to prevent conflicts with real cards */
138 a
[0] = (rand() & 0xff) | 0x80;
139 a
[1] = rand() & 0xff;
140 a
[2] = rand() & 0xff;
141 a
[3] = rand() & 0xff;
142 a
[4] = rand() & 0xff;
143 a
[5] = rand() & 0xff;
145 /* loop through the interfaces, looking for a valid one */
147 for (i
= 0; i
< n
; i
+= ifreq_size(*ifr
) ) {
148 ifrp
= (struct ifreq
*)((char *) ifc
.ifc_buf
+i
);
149 strncpy(ifr
.ifr_name
, ifrp
->ifr_name
, IFNAMSIZ
);
150 /* try to get the address for this interface */
151 # ifdef SIOCGIFHWADDR
152 if (ioctl(sd
, SIOCGIFHWADDR
, &ifr
) < 0)
154 memcpy(a
, (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
, 6);
157 if (ioctl(sd
, SIOCGENADDR
, &ifr
) < 0)
159 memcpy(a
, (unsigned char *) ifr
.ifr_enaddr
, 6);
161 /* XXX we don't have a way of getting the hardware address */
165 # endif /* SIOCGENADDR */
166 # endif /* SIOCGIFHWADDR */
167 /* make sure it's not blank */
168 if (!a
[0] && !a
[1] && !a
[2] && !a
[3] && !a
[4] && !a
[5])
173 /* if we didn't find a valid address, make a random one */
174 /* once again, set multicast bit to avoid conflicts */
175 a
[0] = (rand() & 0xff) | 0x80;
176 a
[1] = rand() & 0xff;
177 a
[2] = rand() & 0xff;
178 a
[3] = rand() & 0xff;
179 a
[4] = rand() & 0xff;
180 a
[5] = rand() & 0xff;
187 /* no networking info, so generate a random address */
188 a
[0] = (rand() & 0xff) | 0x80;
189 a
[1] = rand() & 0xff;
190 a
[2] = rand() & 0xff;
191 a
[3] = rand() & 0xff;
192 a
[4] = rand() & 0xff;
193 a
[5] = rand() & 0xff;
194 #endif /* HAVE_NET_IF_H */
198 /* generate time element of GUID */
200 /* Assume that the gettimeofday() has microsecond granularity */
201 #define MAX_ADJUSTMENT 10
204 gettimeofday(&tv
, 0);
205 if ((last
.tv_sec
== 0) && (last
.tv_usec
== 0)) {
206 clock_seq
= ((rand() & 0xff) << 8) + (rand() & 0xff);
211 if ((tv
.tv_sec
< last
.tv_sec
) ||
212 ((tv
.tv_sec
== last
.tv_sec
) &&
213 (tv
.tv_usec
< last
.tv_usec
))) {
214 clock_seq
= (clock_seq
+1) & 0x1FFF;
216 } else if ((tv
.tv_sec
== last
.tv_sec
) &&
217 (tv
.tv_usec
== last
.tv_usec
)) {
218 if (adjustment
>= MAX_ADJUSTMENT
)
224 clock_reg
= tv
.tv_usec
*10 + adjustment
;
225 clock_reg
+= ((unsigned long long) tv
.tv_sec
)*10000000;
226 clock_reg
+= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
228 clock_high
= clock_reg
>> 32;
229 clock_low
= clock_reg
;
230 temp_clock_seq
= clock_seq
| 0x8000;
231 temp_clock_mid
= (UINT16
)clock_high
;
232 temp_clock_hi_and_version
= (clock_high
>> 16) | 0x1000;
234 /* pack the information into the GUID structure */
236 ((unsigned char*)&Uuid
->Data1
)[3] = (unsigned char)clock_low
;
238 ((unsigned char*)&Uuid
->Data1
)[2] = (unsigned char)clock_low
;
240 ((unsigned char*)&Uuid
->Data1
)[1] = (unsigned char)clock_low
;
242 ((unsigned char*)&Uuid
->Data1
)[0] = (unsigned char)clock_low
;
244 ((unsigned char*)&Uuid
->Data2
)[1] = (unsigned char)temp_clock_mid
;
245 temp_clock_mid
>>= 8;
246 ((unsigned char*)&Uuid
->Data2
)[0] = (unsigned char)temp_clock_mid
;
248 ((unsigned char*)&Uuid
->Data3
)[1] = (unsigned char)temp_clock_hi_and_version
;
249 temp_clock_hi_and_version
>>= 8;
250 ((unsigned char*)&Uuid
->Data3
)[0] = (unsigned char)temp_clock_hi_and_version
;
252 ((unsigned char*)Uuid
->Data4
)[1] = (unsigned char)temp_clock_seq
;
253 temp_clock_seq
>>= 8;
254 ((unsigned char*)Uuid
->Data4
)[0] = (unsigned char)temp_clock_seq
;
256 ((unsigned char*)Uuid
->Data4
)[2] = a
[0];
257 ((unsigned char*)Uuid
->Data4
)[3] = a
[1];
258 ((unsigned char*)Uuid
->Data4
)[4] = a
[2];
259 ((unsigned char*)Uuid
->Data4
)[5] = a
[3];
260 ((unsigned char*)Uuid
->Data4
)[6] = a
[4];
261 ((unsigned char*)Uuid
->Data4
)[7] = a
[5];
263 TRACE("%s", debugstr_guid(Uuid
));