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 /*************************************************************************
70 * UuidCreate [RPCRT4.@]
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;
84 static unsigned char a
[6];
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)
108 #ifdef HAVE_SOCKADDR_SA_LEN
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 /* defined(HAVE_SOCKADDR_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\n", debugstr_guid(Uuid
));
268 /*************************************************************************
269 * UuidCreateSequential [RPCRT4.@]
271 * Creates a 128bit UUID by calling UuidCreate.
272 * New API in Win 2000
275 RPC_STATUS WINAPI
UuidCreateSequential(UUID
*Uuid
)
277 return UuidCreate (Uuid
);
281 /*************************************************************************
282 * RpcStringFreeA [RPCRT4.@]
284 * Frees a character string allocated by the RPC run-time library.
288 * S_OK if successful.
290 RPC_STATUS WINAPI
RpcStringFreeA(unsigned char** String
)
292 HeapFree( GetProcessHeap(), 0, *String
);
298 /*************************************************************************
299 * UuidHash [RPCRT4.@]
301 * Generates a hash value for a given UUID
304 unsigned short WINAPI
UuidHash(UUID
*uuid
, RPC_STATUS
*Status
)
311 /*************************************************************************
312 * UuidToStringA [RPCRT4.@]
314 * Converts a UUID to a string.
316 * UUID format is 8 hex digits, followed by a hyphen then three groups of
317 * 4 hex digits each followed by a hyphen and then 12 hex digits
321 * S_OK if successful.
322 * S_OUT_OF_MEMORY if unsucessful.
324 RPC_STATUS WINAPI
UuidToStringA(UUID
*Uuid
, unsigned char** StringUuid
)
326 *StringUuid
= HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37);
329 return RPC_S_OUT_OF_MEMORY
;
331 sprintf(*StringUuid
, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
332 Uuid
->Data1
, Uuid
->Data2
, Uuid
->Data3
,
333 Uuid
->Data4
[0], Uuid
->Data4
[1], Uuid
->Data4
[2],
334 Uuid
->Data4
[3], Uuid
->Data4
[4], Uuid
->Data4
[5],
335 Uuid
->Data4
[6], Uuid
->Data4
[7] );
340 /***********************************************************************
341 * NdrDllRegisterProxy (RPCRT4.@)
343 HRESULT WINAPI
NdrDllRegisterProxy(
344 HMODULE hDll
, /* [in] */
345 void **pProxyFileList
, /* [???] FIXME: const ProxyFileInfo ** */
346 const CLSID
*pclsid
/* [in] */
349 FIXME("(%x,%p,%s), stub!\n",hDll
,pProxyFileList
,debugstr_guid(pclsid
));
353 /***********************************************************************
354 * RpcServerUseProtseqEpA (RPCRT4.@)
357 RPC_STATUS WINAPI
RpcServerUseProtseqEpA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
)
361 TRACE( "(%s,%u,%s,%p)\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
);
363 /* This should provide the default behaviour */
364 policy
.Length
= sizeof( policy
);
365 policy
.EndpointFlags
= 0;
368 return RpcServerUseProtseqEpExA( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
371 /***********************************************************************
372 * RpcServerUseProtseqEpW (RPCRT4.@)
374 RPC_STATUS WINAPI
RpcServerUseProtseqEpW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
)
378 TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
), SecurityDescriptor
);
380 /* This should provide the default behaviour */
381 policy
.Length
= sizeof( policy
);
382 policy
.EndpointFlags
= 0;
385 return RpcServerUseProtseqEpExW( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
388 /***********************************************************************
389 * RpcServerUseProtseqEpExA (RPCRT4.@)
391 RPC_STATUS WINAPI
RpcServerUseProtseqEpExA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
,
392 PRPC_POLICY lpPolicy
)
394 FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
,
395 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
397 return RPC_S_PROTSEQ_NOT_SUPPORTED
; /* We don't support anything at this point */
400 /***********************************************************************
401 * RpcServerUseProtseqEpExW (RPCRT4.@)
403 RPC_STATUS WINAPI
RpcServerUseProtseqEpExW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
,
404 PRPC_POLICY lpPolicy
)
406 FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
),
408 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
410 return RPC_S_PROTSEQ_NOT_SUPPORTED
; /* We don't support anything at this point */
413 /***********************************************************************
414 * RpcServerRegisterIf (RPCRT4.@)
416 RPC_STATUS WINAPI
RpcServerRegisterIf( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
)
418 /* FIXME: Dump UUID using UuidToStringA */
419 TRACE( "(%p,%p,%p)\n", IfSpec
, MgrTypeUuid
, MgrEpv
);
421 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, (UINT
)-1, NULL
);
424 /***********************************************************************
425 * RpcServerRegisterIfEx (RPCRT4.@)
427 RPC_STATUS WINAPI
RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
428 UINT Flags
, UINT MaxCalls
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
430 /* FIXME: Dump UUID using UuidToStringA */
431 TRACE( "(%p,%p,%p,%u,%u,%p)\n", IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, IfCallbackFn
);
433 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, (UINT
)-1, IfCallbackFn
);
436 /***********************************************************************
437 * RpcServerRegisterIf2 (RPCRT4.@)
439 RPC_STATUS WINAPI
RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
440 UINT Flags
, UINT MaxCalls
, UINT MaxRpcSize
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
442 /* FIXME: Dump UUID using UuidToStringA */
443 FIXME( "(%p,%p,%p,%u,%u,%u,%p): stub\n", IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, MaxRpcSize
, IfCallbackFn
);
445 return RPC_S_UNKNOWN_IF
; /* I guess this return code is as good as any failure */
449 /***********************************************************************
450 * RpcServerRegisterAuthInfoA (RPCRT4.@)
452 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoA( LPSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
455 FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName
, AuthnSvc
, GetKeyFn
, Arg
);
457 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
460 /***********************************************************************
461 * RpcServerRegisterAuthInfoW (RPCRT4.@)
463 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
466 FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName
), AuthnSvc
, GetKeyFn
, Arg
);
468 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
471 /***********************************************************************
472 * RpcServerListen (RPCRT4.@)
474 RPC_STATUS WINAPI
RpcServerListen( UINT MinimumCallThreads
, UINT MaxCalls
, UINT DontWait
)
476 FIXME( "(%u,%u,%u): stub\n", MinimumCallThreads
, MaxCalls
, DontWait
);
478 return RPC_S_NO_PROTSEQS_REGISTERED
; /* Since we don't allow registration this seems reasonable */
481 /***********************************************************************
482 * RpcStringBindingComposeA (RPCRT4.@)
484 RPC_STATUS WINAPI
RpcStringBindingComposeA( LPSTR ObjUuid
, LPSTR Protseq
, LPSTR NetworkAddr
, LPSTR Endpoint
,
485 LPSTR Options
, LPSTR
* StringBinding
)
487 FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
, StringBinding
);
488 *StringBinding
= NULL
;
490 return RPC_S_INVALID_STRING_UUID
; /* Failure */
493 /***********************************************************************
494 * RpcStringBindingComposeW (RPCRT4.@)
496 RPC_STATUS WINAPI
RpcStringBindingComposeW( LPWSTR ObjUuid
, LPWSTR Protseq
, LPWSTR NetworkAddr
, LPWSTR Endpoint
,
497 LPWSTR Options
, LPWSTR
* StringBinding
)
499 FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", debugstr_w( ObjUuid
), debugstr_w( Protseq
), debugstr_w( NetworkAddr
),
500 debugstr_w( Endpoint
), debugstr_w( Options
), StringBinding
);
501 *StringBinding
= NULL
;
503 return RPC_S_INVALID_STRING_UUID
; /* Failure */
506 /***********************************************************************
507 * RpcBindingFromStringBindingA (RPCRT4.@)
509 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( LPSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
511 FIXME( "(%s,%p): stub\n", StringBinding
, Binding
);
513 return RPC_S_INVALID_STRING_BINDING
; /* As good as any failure code */
516 /***********************************************************************
517 * RpcBindingFromStringBindingW (RPCRT4.@)
519 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( LPWSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
521 FIXME( "(%s,%p): stub\n", debugstr_w( StringBinding
), Binding
);
523 return RPC_S_INVALID_STRING_BINDING
; /* As good as any failure code */