4 * Copyright 2000 Huw D M Davies for Codeweavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/windef16.h"
40 #ifdef HAVE_SYS_FILE_H
41 # include <sys/file.h>
43 #ifdef HAVE_SYS_IOCTL_H
44 # include <sys/ioctl.h>
46 #ifdef HAVE_SYS_SOCKET_H
47 # include <sys/socket.h>
49 #ifdef HAVE_SYS_SOCKIO_H
50 # include <sys/sockio.h>
55 #ifdef HAVE_NETINET_IN_H
56 # include <netinet/in.h>
59 #include "wine/debug.h"
61 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
63 /***********************************************************************
67 * hinstDLL [I] handle to the DLL's instance
69 * lpvReserved [I] reserved, must be NULL
77 RPCRT4_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
80 case DLL_PROCESS_ATTACH
:
83 case DLL_PROCESS_DETACH
:
90 /*************************************************************************
91 * UuidCreate [RPCRT4.@]
93 * Creates a 128bit UUID.
94 * Implemented according the DCE specification for UUID generation.
95 * Code is based upon uuid library in e2fsprogs by Theodore Ts'o.
96 * Copyright (C) 1996, 1997 Theodore Ts'o.
100 * S_OK if successful.
102 RPC_STATUS WINAPI
UuidCreate(UUID
*Uuid
)
104 static char has_init
= 0;
105 static unsigned char a
[6];
106 static int adjustment
= 0;
107 static struct timeval last
= {0, 0};
108 static UINT16 clock_seq
;
110 unsigned long long clock_reg
;
111 UINT clock_high
, clock_low
;
112 UINT16 temp_clock_seq
, temp_clock_mid
, temp_clock_hi_and_version
;
115 struct ifreq ifr
, *ifrp
;
121 /* Have we already tried to get the MAC address? */
124 /* BSD 4.4 defines the size of an ifreq to be
125 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
126 * However, under earlier systems, sa_len isn't present, so
127 * the size is just sizeof(struct ifreq)
129 #ifdef HAVE_SOCKADDR_SA_LEN
131 # define max(a,b) ((a) > (b) ? (a) : (b))
133 # define ifreq_size(i) max(sizeof(struct ifreq),\
134 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
136 # define ifreq_size(i) sizeof(struct ifreq)
137 # endif /* defined(HAVE_SOCKADDR_SA_LEN) */
139 sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
141 /* if we can't open a socket, just use random numbers */
142 /* set the multicast bit to prevent conflicts with real cards */
143 a
[0] = (rand() & 0xff) | 0x80;
144 a
[1] = rand() & 0xff;
145 a
[2] = rand() & 0xff;
146 a
[3] = rand() & 0xff;
147 a
[4] = rand() & 0xff;
148 a
[5] = rand() & 0xff;
150 memset(buf
, 0, sizeof(buf
));
151 ifc
.ifc_len
= sizeof(buf
);
153 /* get the ifconf interface */
154 if (ioctl (sd
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
156 /* no ifconf, so just use random numbers */
157 /* set the multicast bit to prevent conflicts with real cards */
158 a
[0] = (rand() & 0xff) | 0x80;
159 a
[1] = rand() & 0xff;
160 a
[2] = rand() & 0xff;
161 a
[3] = rand() & 0xff;
162 a
[4] = rand() & 0xff;
163 a
[5] = rand() & 0xff;
165 /* loop through the interfaces, looking for a valid one */
167 for (i
= 0; i
< n
; i
+= ifreq_size(ifr
) ) {
168 ifrp
= (struct ifreq
*)((char *) ifc
.ifc_buf
+i
);
169 strncpy(ifr
.ifr_name
, ifrp
->ifr_name
, IFNAMSIZ
);
170 /* try to get the address for this interface */
171 # ifdef SIOCGIFHWADDR
172 if (ioctl(sd
, SIOCGIFHWADDR
, &ifr
) < 0)
174 memcpy(a
, (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
, 6);
177 if (ioctl(sd
, SIOCGENADDR
, &ifr
) < 0)
179 memcpy(a
, (unsigned char *) ifr
.ifr_enaddr
, 6);
181 /* XXX we don't have a way of getting the hardware address */
185 # endif /* SIOCGENADDR */
186 # endif /* SIOCGIFHWADDR */
187 /* make sure it's not blank */
188 if (!a
[0] && !a
[1] && !a
[2] && !a
[3] && !a
[4] && !a
[5])
193 /* if we didn't find a valid address, make a random one */
194 /* once again, set multicast bit to avoid conflicts */
195 a
[0] = (rand() & 0xff) | 0x80;
196 a
[1] = rand() & 0xff;
197 a
[2] = rand() & 0xff;
198 a
[3] = rand() & 0xff;
199 a
[4] = rand() & 0xff;
200 a
[5] = rand() & 0xff;
207 /* no networking info, so generate a random address */
208 a
[0] = (rand() & 0xff) | 0x80;
209 a
[1] = rand() & 0xff;
210 a
[2] = rand() & 0xff;
211 a
[3] = rand() & 0xff;
212 a
[4] = rand() & 0xff;
213 a
[5] = rand() & 0xff;
214 #endif /* HAVE_NET_IF_H */
218 /* generate time element of GUID */
220 /* Assume that the gettimeofday() has microsecond granularity */
221 #define MAX_ADJUSTMENT 10
224 gettimeofday(&tv
, 0);
225 if ((last
.tv_sec
== 0) && (last
.tv_usec
== 0)) {
226 clock_seq
= ((rand() & 0xff) << 8) + (rand() & 0xff);
231 if ((tv
.tv_sec
< last
.tv_sec
) ||
232 ((tv
.tv_sec
== last
.tv_sec
) &&
233 (tv
.tv_usec
< last
.tv_usec
))) {
234 clock_seq
= (clock_seq
+1) & 0x1FFF;
236 } else if ((tv
.tv_sec
== last
.tv_sec
) &&
237 (tv
.tv_usec
== last
.tv_usec
)) {
238 if (adjustment
>= MAX_ADJUSTMENT
)
244 clock_reg
= tv
.tv_usec
*10 + adjustment
;
245 clock_reg
+= ((unsigned long long) tv
.tv_sec
)*10000000;
246 clock_reg
+= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
248 clock_high
= clock_reg
>> 32;
249 clock_low
= clock_reg
;
250 temp_clock_seq
= clock_seq
| 0x8000;
251 temp_clock_mid
= (UINT16
)clock_high
;
252 temp_clock_hi_and_version
= (clock_high
>> 16) | 0x1000;
254 /* pack the information into the GUID structure */
256 ((unsigned char*)&Uuid
->Data1
)[3] = (unsigned char)clock_low
;
258 ((unsigned char*)&Uuid
->Data1
)[2] = (unsigned char)clock_low
;
260 ((unsigned char*)&Uuid
->Data1
)[1] = (unsigned char)clock_low
;
262 ((unsigned char*)&Uuid
->Data1
)[0] = (unsigned char)clock_low
;
264 ((unsigned char*)&Uuid
->Data2
)[1] = (unsigned char)temp_clock_mid
;
265 temp_clock_mid
>>= 8;
266 ((unsigned char*)&Uuid
->Data2
)[0] = (unsigned char)temp_clock_mid
;
268 ((unsigned char*)&Uuid
->Data3
)[1] = (unsigned char)temp_clock_hi_and_version
;
269 temp_clock_hi_and_version
>>= 8;
270 ((unsigned char*)&Uuid
->Data3
)[0] = (unsigned char)temp_clock_hi_and_version
;
272 ((unsigned char*)Uuid
->Data4
)[1] = (unsigned char)temp_clock_seq
;
273 temp_clock_seq
>>= 8;
274 ((unsigned char*)Uuid
->Data4
)[0] = (unsigned char)temp_clock_seq
;
276 ((unsigned char*)Uuid
->Data4
)[2] = a
[0];
277 ((unsigned char*)Uuid
->Data4
)[3] = a
[1];
278 ((unsigned char*)Uuid
->Data4
)[4] = a
[2];
279 ((unsigned char*)Uuid
->Data4
)[5] = a
[3];
280 ((unsigned char*)Uuid
->Data4
)[6] = a
[4];
281 ((unsigned char*)Uuid
->Data4
)[7] = a
[5];
283 TRACE("%s\n", debugstr_guid(Uuid
));
289 /*************************************************************************
290 * UuidCreateSequential [RPCRT4.@]
292 * Creates a 128bit UUID by calling UuidCreate.
293 * New API in Win 2000
296 RPC_STATUS WINAPI
UuidCreateSequential(UUID
*Uuid
)
298 return UuidCreate (Uuid
);
302 /*************************************************************************
303 * RpcStringFreeA [RPCRT4.@]
305 * Frees a character string allocated by the RPC run-time library.
309 * S_OK if successful.
311 RPC_STATUS WINAPI
RpcStringFreeA(unsigned char** String
)
313 HeapFree( GetProcessHeap(), 0, *String
);
319 /*************************************************************************
320 * UuidHash [RPCRT4.@]
322 * Generates a hash value for a given UUID
325 unsigned short WINAPI
UuidHash(UUID
*uuid
, RPC_STATUS
*Status
)
332 /*************************************************************************
333 * UuidToStringA [RPCRT4.@]
335 * Converts a UUID to a string.
337 * UUID format is 8 hex digits, followed by a hyphen then three groups of
338 * 4 hex digits each followed by a hyphen and then 12 hex digits
342 * S_OK if successful.
343 * S_OUT_OF_MEMORY if unsucessful.
345 RPC_STATUS WINAPI
UuidToStringA(UUID
*Uuid
, unsigned char** StringUuid
)
347 *StringUuid
= HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37);
350 return RPC_S_OUT_OF_MEMORY
;
352 sprintf(*StringUuid
, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
353 Uuid
->Data1
, Uuid
->Data2
, Uuid
->Data3
,
354 Uuid
->Data4
[0], Uuid
->Data4
[1], Uuid
->Data4
[2],
355 Uuid
->Data4
[3], Uuid
->Data4
[4], Uuid
->Data4
[5],
356 Uuid
->Data4
[6], Uuid
->Data4
[7] );
361 /***********************************************************************
362 * UuidFromStringA (RPCRT4.@)
364 RPC_STATUS WINAPI
UuidFromStringA(unsigned char *str
, UUID
*uuid
)
366 FIXME("%s %p\n",debugstr_a(str
),uuid
);
367 return RPC_S_INVALID_STRING_UUID
;
370 /***********************************************************************
371 * UuidFromStringW (RPCRT4.@)
373 RPC_STATUS WINAPI
UuidFromStringW(unsigned short *str
, UUID
*uuid
)
375 FIXME("%s %p\n",debugstr_w(str
),uuid
);
376 return RPC_S_INVALID_STRING_UUID
;
379 /***********************************************************************
380 * NdrDllRegisterProxy (RPCRT4.@)
382 HRESULT WINAPI
NdrDllRegisterProxy(
383 HMODULE hDll
, /* [in] */
384 const ProxyFileInfo
**pProxyFileList
, /* [in] */
385 const CLSID
*pclsid
/* [in] */
388 FIXME("(%x,%p,%s), stub!\n",hDll
,pProxyFileList
,debugstr_guid(pclsid
));
392 /***********************************************************************
393 * RpcServerUseProtseqEpA (RPCRT4.@)
396 RPC_STATUS WINAPI
RpcServerUseProtseqEpA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
)
400 TRACE( "(%s,%u,%s,%p)\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
);
402 /* This should provide the default behaviour */
403 policy
.Length
= sizeof( policy
);
404 policy
.EndpointFlags
= 0;
407 return RpcServerUseProtseqEpExA( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
410 /***********************************************************************
411 * RpcServerUseProtseqEpW (RPCRT4.@)
413 RPC_STATUS WINAPI
RpcServerUseProtseqEpW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
)
417 TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
), SecurityDescriptor
);
419 /* This should provide the default behaviour */
420 policy
.Length
= sizeof( policy
);
421 policy
.EndpointFlags
= 0;
424 return RpcServerUseProtseqEpExW( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
427 /***********************************************************************
428 * RpcServerUseProtseqEpExA (RPCRT4.@)
430 RPC_STATUS WINAPI
RpcServerUseProtseqEpExA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
,
431 PRPC_POLICY lpPolicy
)
433 FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
,
434 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
436 return RPC_S_PROTSEQ_NOT_SUPPORTED
; /* We don't support anything at this point */
439 /***********************************************************************
440 * RpcServerUseProtseqEpExW (RPCRT4.@)
442 RPC_STATUS WINAPI
RpcServerUseProtseqEpExW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
,
443 PRPC_POLICY lpPolicy
)
445 FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
),
447 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
449 return RPC_S_PROTSEQ_NOT_SUPPORTED
; /* We don't support anything at this point */
452 /***********************************************************************
453 * RpcServerRegisterIf (RPCRT4.@)
455 RPC_STATUS WINAPI
RpcServerRegisterIf( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
)
457 /* FIXME: Dump UUID using UuidToStringA */
458 TRACE( "(%p,%p,%p)\n", IfSpec
, MgrTypeUuid
, MgrEpv
);
460 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, (UINT
)-1, NULL
);
463 /***********************************************************************
464 * RpcServerRegisterIfEx (RPCRT4.@)
466 RPC_STATUS WINAPI
RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
467 UINT Flags
, UINT MaxCalls
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
469 /* FIXME: Dump UUID using UuidToStringA */
470 TRACE( "(%p,%p,%p,%u,%u,%p)\n", IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, IfCallbackFn
);
472 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, (UINT
)-1, IfCallbackFn
);
475 /***********************************************************************
476 * RpcServerRegisterIf2 (RPCRT4.@)
478 RPC_STATUS WINAPI
RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
479 UINT Flags
, UINT MaxCalls
, UINT MaxRpcSize
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
481 /* FIXME: Dump UUID using UuidToStringA */
482 FIXME( "(%p,%p,%p,%u,%u,%u,%p): stub\n", IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, MaxRpcSize
, IfCallbackFn
);
484 return RPC_S_UNKNOWN_IF
; /* I guess this return code is as good as any failure */
488 /***********************************************************************
489 * RpcServerRegisterAuthInfoA (RPCRT4.@)
491 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoA( LPSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
494 FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName
, AuthnSvc
, GetKeyFn
, Arg
);
496 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
499 /***********************************************************************
500 * RpcServerRegisterAuthInfoW (RPCRT4.@)
502 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
505 FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName
), AuthnSvc
, GetKeyFn
, Arg
);
507 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
510 /***********************************************************************
511 * RpcServerListen (RPCRT4.@)
513 RPC_STATUS WINAPI
RpcServerListen( UINT MinimumCallThreads
, UINT MaxCalls
, UINT DontWait
)
515 FIXME( "(%u,%u,%u): stub\n", MinimumCallThreads
, MaxCalls
, DontWait
);
517 return RPC_S_NO_PROTSEQS_REGISTERED
; /* Since we don't allow registration this seems reasonable */
520 /***********************************************************************
521 * RpcStringBindingComposeA (RPCRT4.@)
523 RPC_STATUS WINAPI
RpcStringBindingComposeA( LPSTR ObjUuid
, LPSTR Protseq
, LPSTR NetworkAddr
, LPSTR Endpoint
,
524 LPSTR Options
, LPSTR
* StringBinding
)
526 FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
, StringBinding
);
527 *StringBinding
= NULL
;
529 return RPC_S_INVALID_STRING_UUID
; /* Failure */
532 /***********************************************************************
533 * RpcStringBindingComposeW (RPCRT4.@)
535 RPC_STATUS WINAPI
RpcStringBindingComposeW( LPWSTR ObjUuid
, LPWSTR Protseq
, LPWSTR NetworkAddr
, LPWSTR Endpoint
,
536 LPWSTR Options
, LPWSTR
* StringBinding
)
538 FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", debugstr_w( ObjUuid
), debugstr_w( Protseq
), debugstr_w( NetworkAddr
),
539 debugstr_w( Endpoint
), debugstr_w( Options
), StringBinding
);
540 *StringBinding
= NULL
;
542 return RPC_S_INVALID_STRING_UUID
; /* Failure */
545 /***********************************************************************
546 * RpcBindingFree (RPCRT4.@)
548 RPC_STATUS WINAPI
RpcBindingFree(RPC_BINDING_HANDLE
* Binding
)
550 FIXME("(%p): stub\n", Binding
);
553 /***********************************************************************
554 * RpcBindingFromStringBindingA (RPCRT4.@)
556 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( LPSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
558 FIXME( "(%s,%p): stub\n", StringBinding
, Binding
);
560 return RPC_S_INVALID_STRING_BINDING
; /* As good as any failure code */
563 /***********************************************************************
564 * RpcBindingFromStringBindingW (RPCRT4.@)
566 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( LPWSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
568 FIXME( "(%s,%p): stub\n", debugstr_w( StringBinding
), Binding
);
570 return RPC_S_INVALID_STRING_BINDING
; /* As good as any failure code */
573 /***********************************************************************
574 * NdrDllCanUnloadNow (RPCRT4.@)
576 HRESULT WINAPI
NdrDllCanUnloadNow(CStdPSFactoryBuffer
*pPSFactoryBuffer
)
578 FIXME("%p\n",pPSFactoryBuffer
);
582 /***********************************************************************
583 * NdrDllGetClassObject (RPCRT4.@)
585 HRESULT WINAPI
NdrDllGetClassObject(
586 REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
,
587 const ProxyFileInfo
** pProxyFileList
,
588 const CLSID
* pclsid
,
589 CStdPSFactoryBuffer
* pPSFactoryBuffer
)
593 return RPC_S_UNKNOWN_IF
;
596 /***********************************************************************
597 * DllRegisterServer (RPCRT4.@)
600 HRESULT WINAPI
RPCRT4_DllRegisterServer( void )
602 FIXME( "(): stub\n" );