16 #include "wine/windef16.h"
21 #ifdef HAVE_SYS_FILE_H
22 # include <sys/file.h>
24 #include <sys/ioctl.h>
25 #ifdef HAVE_SYS_SOCKET_H
26 # include <sys/socket.h>
28 #ifdef HAVE_SYS_SOCKIO_H
29 # include <sys/sockio.h>
34 #ifdef HAVE_NETINET_IN_H
35 # include <netinet/in.h>
38 #include "debugtools.h"
40 DEFAULT_DEBUG_CHANNEL(ole
);
42 /***********************************************************************
46 * hinstDLL [I] handle to the DLL's instance
48 * lpvReserved [I] reserved, must be NULL
56 RPCRT4_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
59 case DLL_PROCESS_ATTACH
:
62 case DLL_PROCESS_DETACH
:
69 /*************************************************************************
72 * Creates a 128bit UUID.
73 * Implemented according the DCE specification for UUID generation.
74 * Code is based upon uuid library in e2fsprogs by Theodore Ts'o.
75 * Copyright (C) 1996, 1997 Theodore Ts'o.
81 RPC_STATUS WINAPI
UuidCreate(UUID
*Uuid
)
83 static char has_init
= 0;
85 static int adjustment
= 0;
86 static struct timeval last
= {0, 0};
87 static UINT16 clock_seq
;
89 unsigned long long clock_reg
;
90 UINT clock_high
, clock_low
;
91 UINT16 temp_clock_seq
, temp_clock_mid
, temp_clock_hi_and_version
;
94 struct ifreq ifr
, *ifrp
;
100 /* Have we already tried to get the MAC address? */
103 /* BSD 4.4 defines the size of an ifreq to be
104 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
105 * However, under earlier systems, sa_len isn't present, so
106 * the size is just sizeof(struct ifreq)
110 # define max(a,b) ((a) > (b) ? (a) : (b))
112 # define ifreq_size(i) max(sizeof(struct ifreq),\
113 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
115 # define ifreq_size(i) sizeof(struct ifreq)
116 # endif /* HAVE_SA_LEN */
118 sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
120 /* if we can't open a socket, just use random numbers */
121 /* set the multicast bit to prevent conflicts with real cards */
122 a
[0] = (rand() & 0xff) | 0x80;
123 a
[1] = rand() & 0xff;
124 a
[2] = rand() & 0xff;
125 a
[3] = rand() & 0xff;
126 a
[4] = rand() & 0xff;
127 a
[5] = rand() & 0xff;
129 memset(buf
, 0, sizeof(buf
));
130 ifc
.ifc_len
= sizeof(buf
);
132 /* get the ifconf interface */
133 if (ioctl (sd
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
135 /* no ifconf, so just use random numbers */
136 /* set the multicast bit to prevent conflicts with real cards */
137 a
[0] = (rand() & 0xff) | 0x80;
138 a
[1] = rand() & 0xff;
139 a
[2] = rand() & 0xff;
140 a
[3] = rand() & 0xff;
141 a
[4] = rand() & 0xff;
142 a
[5] = rand() & 0xff;
144 /* loop through the interfaces, looking for a valid one */
146 for (i
= 0; i
< n
; i
+= ifreq_size(*ifr
) ) {
147 ifrp
= (struct ifreq
*)((char *) ifc
.ifc_buf
+i
);
148 strncpy(ifr
.ifr_name
, ifrp
->ifr_name
, IFNAMSIZ
);
149 /* try to get the address for this interface */
150 # ifdef SIOCGIFHWADDR
151 if (ioctl(sd
, SIOCGIFHWADDR
, &ifr
) < 0)
153 memcpy(a
, (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
, 6);
156 if (ioctl(sd
, SIOCGENADDR
, &ifr
) < 0)
158 memcpy(a
, (unsigned char *) ifr
.ifr_enaddr
, 6);
160 /* XXX we don't have a way of getting the hardware address */
164 # endif /* SIOCGENADDR */
165 # endif /* SIOCGIFHWADDR */
166 /* make sure it's not blank */
167 if (!a
[0] && !a
[1] && !a
[2] && !a
[3] && !a
[4] && !a
[5])
172 /* if we didn't find a valid address, make a random one */
173 /* once again, set multicast bit to avoid conflicts */
174 a
[0] = (rand() & 0xff) | 0x80;
175 a
[1] = rand() & 0xff;
176 a
[2] = rand() & 0xff;
177 a
[3] = rand() & 0xff;
178 a
[4] = rand() & 0xff;
179 a
[5] = rand() & 0xff;
186 /* no networking info, so generate a random address */
187 a
[0] = (rand() & 0xff) | 0x80;
188 a
[1] = rand() & 0xff;
189 a
[2] = rand() & 0xff;
190 a
[3] = rand() & 0xff;
191 a
[4] = rand() & 0xff;
192 a
[5] = rand() & 0xff;
193 #endif /* HAVE_NET_IF_H */
197 /* generate time element of GUID */
199 /* Assume that the gettimeofday() has microsecond granularity */
200 #define MAX_ADJUSTMENT 10
203 gettimeofday(&tv
, 0);
204 if ((last
.tv_sec
== 0) && (last
.tv_usec
== 0)) {
205 clock_seq
= ((rand() & 0xff) << 8) + (rand() & 0xff);
210 if ((tv
.tv_sec
< last
.tv_sec
) ||
211 ((tv
.tv_sec
== last
.tv_sec
) &&
212 (tv
.tv_usec
< last
.tv_usec
))) {
213 clock_seq
= (clock_seq
+1) & 0x1FFF;
215 } else if ((tv
.tv_sec
== last
.tv_sec
) &&
216 (tv
.tv_usec
== last
.tv_usec
)) {
217 if (adjustment
>= MAX_ADJUSTMENT
)
223 clock_reg
= tv
.tv_usec
*10 + adjustment
;
224 clock_reg
+= ((unsigned long long) tv
.tv_sec
)*10000000;
225 clock_reg
+= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
227 clock_high
= clock_reg
>> 32;
228 clock_low
= clock_reg
;
229 temp_clock_seq
= clock_seq
| 0x8000;
230 temp_clock_mid
= (UINT16
)clock_high
;
231 temp_clock_hi_and_version
= (clock_high
>> 16) | 0x1000;
233 /* pack the information into the GUID structure */
235 ((unsigned char*)&Uuid
->Data1
)[3] = (unsigned char)clock_low
;
237 ((unsigned char*)&Uuid
->Data1
)[2] = (unsigned char)clock_low
;
239 ((unsigned char*)&Uuid
->Data1
)[1] = (unsigned char)clock_low
;
241 ((unsigned char*)&Uuid
->Data1
)[0] = (unsigned char)clock_low
;
243 ((unsigned char*)&Uuid
->Data2
)[1] = (unsigned char)temp_clock_mid
;
244 temp_clock_mid
>>= 8;
245 ((unsigned char*)&Uuid
->Data2
)[0] = (unsigned char)temp_clock_mid
;
247 ((unsigned char*)&Uuid
->Data3
)[1] = (unsigned char)temp_clock_hi_and_version
;
248 temp_clock_hi_and_version
>>= 8;
249 ((unsigned char*)&Uuid
->Data3
)[0] = (unsigned char)temp_clock_hi_and_version
;
251 ((unsigned char*)Uuid
->Data4
)[1] = (unsigned char)temp_clock_seq
;
252 temp_clock_seq
>>= 8;
253 ((unsigned char*)Uuid
->Data4
)[0] = (unsigned char)temp_clock_seq
;
255 ((unsigned char*)Uuid
->Data4
)[2] = a
[0];
256 ((unsigned char*)Uuid
->Data4
)[3] = a
[1];
257 ((unsigned char*)Uuid
->Data4
)[4] = a
[2];
258 ((unsigned char*)Uuid
->Data4
)[5] = a
[3];
259 ((unsigned char*)Uuid
->Data4
)[6] = a
[4];
260 ((unsigned char*)Uuid
->Data4
)[7] = a
[5];
262 TRACE("%s", debugstr_guid(Uuid
));
267 /*************************************************************************
268 * RpcStringFreeA [RPCRT4.436]
270 * Frees a character string allocated by the RPC run-time library.
274 * S_OK if successful.
276 RPC_STATUS WINAPI
RpcStringFreeA(unsigned char** String
)
278 HeapFree( GetProcessHeap(), 0, *String
);
283 /*************************************************************************
284 * UuidToStringA [RPCRT4.450]
286 * Converts a UUID to a string.
288 * UUID format is 8 hex digits, followed by a hyphen then three groups of
289 * 4 hex digits each followed by a hyphen and then 12 hex digits
293 * S_OK if successful.
294 * S_OUT_OF_MEMORY if unsucessful.
296 RPC_STATUS WINAPI
UuidToStringA(UUID
*Uuid
, unsigned char** StringUuid
)
298 *StringUuid
= HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37);
301 /* FIXME: this should be RPC_S_OUT_OF_MEMORY */
303 return ERROR_OUTOFMEMORY
;
305 sprintf(*StringUuid
, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
306 Uuid
->Data1
, Uuid
->Data2
, Uuid
->Data3
,
307 Uuid
->Data4
[0], Uuid
->Data4
[1], Uuid
->Data4
[2],
308 Uuid
->Data4
[3], Uuid
->Data4
[4], Uuid
->Data4
[5],
309 Uuid
->Data4
[6], Uuid
->Data4
[7] );
311 return S_OK
; /*FIXME: this should be RPC_S_OK */
314 /***********************************************************************
315 * NdrDllRegisterProxy (RPCRT4.@)
317 HRESULT WINAPI
NdrDllRegisterProxy(
318 HMODULE hDll
, /* [in] */
319 void **pProxyFileList
, /* [???] FIXME: const ProxyFileInfo ** */
320 const CLSID
*pclsid
/* [in] */
322 FIXME("(%x,%p,%s), stub!\n",hDll
,pProxyFileList
,debugstr_guid(pclsid
));