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
27 #ifdef HAVE_SYS_TIME_H
28 # include <sys/time.h>
35 #include "wine/windef16.h"
44 #ifdef HAVE_SYS_FILE_H
45 # include <sys/file.h>
47 #ifdef HAVE_SYS_IOCTL_H
48 # include <sys/ioctl.h>
50 #ifdef HAVE_SYS_SOCKET_H
51 # include <sys/socket.h>
53 #ifdef HAVE_SYS_SOCKIO_H
54 # include <sys/sockio.h>
59 #ifdef HAVE_NETINET_IN_H
60 # include <netinet/in.h>
63 #include "wine/debug.h"
65 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
67 /***********************************************************************
71 * hinstDLL [I] handle to the DLL's instance
73 * lpvReserved [I] reserved, must be NULL
81 RPCRT4_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
84 case DLL_PROCESS_ATTACH
:
87 case DLL_PROCESS_DETACH
:
94 /*************************************************************************
95 * UuidCreate [RPCRT4.@]
97 * Creates a 128bit UUID.
98 * Implemented according the DCE specification for UUID generation.
99 * Code is based upon uuid library in e2fsprogs by Theodore Ts'o.
100 * Copyright (C) 1996, 1997 Theodore Ts'o.
104 * S_OK if successful.
106 RPC_STATUS WINAPI
UuidCreate(UUID
*Uuid
)
108 static char has_init
= 0;
109 static unsigned char a
[6];
110 static int adjustment
= 0;
111 static struct timeval last
= {0, 0};
112 static UINT16 clock_seq
;
114 unsigned long long clock_reg
;
115 UINT clock_high
, clock_low
;
116 UINT16 temp_clock_seq
, temp_clock_mid
, temp_clock_hi_and_version
;
119 struct ifreq ifr
, *ifrp
;
125 /* Have we already tried to get the MAC address? */
128 /* BSD 4.4 defines the size of an ifreq to be
129 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
130 * However, under earlier systems, sa_len isn't present, so
131 * the size is just sizeof(struct ifreq)
133 #ifdef HAVE_SOCKADDR_SA_LEN
135 # define max(a,b) ((a) > (b) ? (a) : (b))
137 # define ifreq_size(i) max(sizeof(struct ifreq),\
138 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
140 # define ifreq_size(i) sizeof(struct ifreq)
141 # endif /* defined(HAVE_SOCKADDR_SA_LEN) */
143 sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
145 /* if we can't open a socket, just use random numbers */
146 /* set the multicast bit to prevent conflicts with real cards */
147 a
[0] = (rand() & 0xff) | 0x80;
148 a
[1] = rand() & 0xff;
149 a
[2] = rand() & 0xff;
150 a
[3] = rand() & 0xff;
151 a
[4] = rand() & 0xff;
152 a
[5] = rand() & 0xff;
154 memset(buf
, 0, sizeof(buf
));
155 ifc
.ifc_len
= sizeof(buf
);
157 /* get the ifconf interface */
158 if (ioctl (sd
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
160 /* no ifconf, so just use random numbers */
161 /* set the multicast bit to prevent conflicts with real cards */
162 a
[0] = (rand() & 0xff) | 0x80;
163 a
[1] = rand() & 0xff;
164 a
[2] = rand() & 0xff;
165 a
[3] = rand() & 0xff;
166 a
[4] = rand() & 0xff;
167 a
[5] = rand() & 0xff;
169 /* loop through the interfaces, looking for a valid one */
171 for (i
= 0; i
< n
; i
+= ifreq_size(ifr
) ) {
172 ifrp
= (struct ifreq
*)((char *) ifc
.ifc_buf
+i
);
173 strncpy(ifr
.ifr_name
, ifrp
->ifr_name
, IFNAMSIZ
);
174 /* try to get the address for this interface */
175 # ifdef SIOCGIFHWADDR
176 if (ioctl(sd
, SIOCGIFHWADDR
, &ifr
) < 0)
178 memcpy(a
, (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
, 6);
181 if (ioctl(sd
, SIOCGENADDR
, &ifr
) < 0)
183 memcpy(a
, (unsigned char *) ifr
.ifr_enaddr
, 6);
185 /* XXX we don't have a way of getting the hardware address */
189 # endif /* SIOCGENADDR */
190 # endif /* SIOCGIFHWADDR */
191 /* make sure it's not blank */
192 if (!a
[0] && !a
[1] && !a
[2] && !a
[3] && !a
[4] && !a
[5])
197 /* if we didn't find a valid address, make a random one */
198 /* once again, set multicast bit to avoid conflicts */
199 a
[0] = (rand() & 0xff) | 0x80;
200 a
[1] = rand() & 0xff;
201 a
[2] = rand() & 0xff;
202 a
[3] = rand() & 0xff;
203 a
[4] = rand() & 0xff;
204 a
[5] = rand() & 0xff;
211 /* no networking info, so generate a random address */
212 a
[0] = (rand() & 0xff) | 0x80;
213 a
[1] = rand() & 0xff;
214 a
[2] = rand() & 0xff;
215 a
[3] = rand() & 0xff;
216 a
[4] = rand() & 0xff;
217 a
[5] = rand() & 0xff;
218 #endif /* HAVE_NET_IF_H */
222 /* generate time element of GUID */
224 /* Assume that the gettimeofday() has microsecond granularity */
225 #define MAX_ADJUSTMENT 10
228 gettimeofday(&tv
, 0);
229 if ((last
.tv_sec
== 0) && (last
.tv_usec
== 0)) {
230 clock_seq
= ((rand() & 0xff) << 8) + (rand() & 0xff);
235 if ((tv
.tv_sec
< last
.tv_sec
) ||
236 ((tv
.tv_sec
== last
.tv_sec
) &&
237 (tv
.tv_usec
< last
.tv_usec
))) {
238 clock_seq
= (clock_seq
+1) & 0x1FFF;
240 } else if ((tv
.tv_sec
== last
.tv_sec
) &&
241 (tv
.tv_usec
== last
.tv_usec
)) {
242 if (adjustment
>= MAX_ADJUSTMENT
)
248 clock_reg
= tv
.tv_usec
*10 + adjustment
;
249 clock_reg
+= ((unsigned long long) tv
.tv_sec
)*10000000;
250 clock_reg
+= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
252 clock_high
= clock_reg
>> 32;
253 clock_low
= clock_reg
;
254 temp_clock_seq
= clock_seq
| 0x8000;
255 temp_clock_mid
= (UINT16
)clock_high
;
256 temp_clock_hi_and_version
= (clock_high
>> 16) | 0x1000;
258 /* pack the information into the GUID structure */
260 ((unsigned char*)&Uuid
->Data1
)[3] = (unsigned char)clock_low
;
262 ((unsigned char*)&Uuid
->Data1
)[2] = (unsigned char)clock_low
;
264 ((unsigned char*)&Uuid
->Data1
)[1] = (unsigned char)clock_low
;
266 ((unsigned char*)&Uuid
->Data1
)[0] = (unsigned char)clock_low
;
268 ((unsigned char*)&Uuid
->Data2
)[1] = (unsigned char)temp_clock_mid
;
269 temp_clock_mid
>>= 8;
270 ((unsigned char*)&Uuid
->Data2
)[0] = (unsigned char)temp_clock_mid
;
272 ((unsigned char*)&Uuid
->Data3
)[1] = (unsigned char)temp_clock_hi_and_version
;
273 temp_clock_hi_and_version
>>= 8;
274 ((unsigned char*)&Uuid
->Data3
)[0] = (unsigned char)temp_clock_hi_and_version
;
276 ((unsigned char*)Uuid
->Data4
)[1] = (unsigned char)temp_clock_seq
;
277 temp_clock_seq
>>= 8;
278 ((unsigned char*)Uuid
->Data4
)[0] = (unsigned char)temp_clock_seq
;
280 ((unsigned char*)Uuid
->Data4
)[2] = a
[0];
281 ((unsigned char*)Uuid
->Data4
)[3] = a
[1];
282 ((unsigned char*)Uuid
->Data4
)[4] = a
[2];
283 ((unsigned char*)Uuid
->Data4
)[5] = a
[3];
284 ((unsigned char*)Uuid
->Data4
)[6] = a
[4];
285 ((unsigned char*)Uuid
->Data4
)[7] = a
[5];
287 TRACE("%s\n", debugstr_guid(Uuid
));
293 /*************************************************************************
294 * UuidCreateSequential [RPCRT4.@]
296 * Creates a 128bit UUID by calling UuidCreate.
297 * New API in Win 2000
300 RPC_STATUS WINAPI
UuidCreateSequential(UUID
*Uuid
)
302 return UuidCreate (Uuid
);
306 /*************************************************************************
307 * RpcStringFreeA [RPCRT4.@]
309 * Frees a character string allocated by the RPC run-time library.
313 * S_OK if successful.
315 RPC_STATUS WINAPI
RpcStringFreeA(LPSTR
* String
)
317 HeapFree( GetProcessHeap(), 0, *String
);
323 /*************************************************************************
324 * UuidHash [RPCRT4.@]
326 * Generates a hash value for a given UUID
329 unsigned short WINAPI
UuidHash(UUID
*uuid
, RPC_STATUS
*Status
)
336 /*************************************************************************
337 * UuidToStringA [RPCRT4.@]
339 * Converts a UUID to a string.
341 * UUID format is 8 hex digits, followed by a hyphen then three groups of
342 * 4 hex digits each followed by a hyphen and then 12 hex digits
346 * S_OK if successful.
347 * S_OUT_OF_MEMORY if unsucessful.
349 RPC_STATUS WINAPI
UuidToStringA(UUID
*Uuid
, LPSTR
* StringUuid
)
351 *StringUuid
= HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37);
354 return RPC_S_OUT_OF_MEMORY
;
356 sprintf(*StringUuid
, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
357 Uuid
->Data1
, Uuid
->Data2
, Uuid
->Data3
,
358 Uuid
->Data4
[0], Uuid
->Data4
[1], Uuid
->Data4
[2],
359 Uuid
->Data4
[3], Uuid
->Data4
[4], Uuid
->Data4
[5],
360 Uuid
->Data4
[6], Uuid
->Data4
[7] );
365 /***********************************************************************
366 * UuidFromStringA (RPCRT4.@)
368 RPC_STATUS WINAPI
UuidFromStringA(LPSTR str
, UUID
*uuid
)
370 FIXME("%s %p\n",debugstr_a(str
),uuid
);
371 return RPC_S_INVALID_STRING_UUID
;
374 /***********************************************************************
375 * UuidFromStringW (RPCRT4.@)
377 RPC_STATUS WINAPI
UuidFromStringW(LPWSTR str
, UUID
*uuid
)
379 FIXME("%s %p\n",debugstr_w(str
),uuid
);
380 return RPC_S_INVALID_STRING_UUID
;
383 /***********************************************************************
384 * NdrDllRegisterProxy (RPCRT4.@)
386 HRESULT WINAPI
NdrDllRegisterProxy(
387 HMODULE hDll
, /* [in] */
388 const ProxyFileInfo
**pProxyFileList
, /* [in] */
389 const CLSID
*pclsid
/* [in] */
392 FIXME("(%x,%p,%s), stub!\n",hDll
,pProxyFileList
,debugstr_guid(pclsid
));
396 /***********************************************************************
397 * RpcServerUseProtseqEpA (RPCRT4.@)
400 RPC_STATUS WINAPI
RpcServerUseProtseqEpA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
)
404 TRACE( "(%s,%u,%s,%p)\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
);
406 /* This should provide the default behaviour */
407 policy
.Length
= sizeof( policy
);
408 policy
.EndpointFlags
= 0;
411 return RpcServerUseProtseqEpExA( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
414 /***********************************************************************
415 * RpcServerUseProtseqEpW (RPCRT4.@)
417 RPC_STATUS WINAPI
RpcServerUseProtseqEpW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
)
421 TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
), SecurityDescriptor
);
423 /* This should provide the default behaviour */
424 policy
.Length
= sizeof( policy
);
425 policy
.EndpointFlags
= 0;
428 return RpcServerUseProtseqEpExW( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
431 /***********************************************************************
432 * RpcServerUseProtseqEpExA (RPCRT4.@)
434 RPC_STATUS WINAPI
RpcServerUseProtseqEpExA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
,
435 PRPC_POLICY lpPolicy
)
437 FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
,
438 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
440 return RPC_S_PROTSEQ_NOT_SUPPORTED
; /* We don't support anything at this point */
443 /***********************************************************************
444 * RpcServerUseProtseqEpExW (RPCRT4.@)
446 RPC_STATUS WINAPI
RpcServerUseProtseqEpExW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
,
447 PRPC_POLICY lpPolicy
)
449 FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
),
451 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
453 return RPC_S_PROTSEQ_NOT_SUPPORTED
; /* We don't support anything at this point */
456 /***********************************************************************
457 * RpcServerRegisterIf (RPCRT4.@)
459 RPC_STATUS WINAPI
RpcServerRegisterIf( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
)
461 /* FIXME: Dump UUID using UuidToStringA */
462 TRACE( "(%p,%p,%p)\n", IfSpec
, MgrTypeUuid
, MgrEpv
);
464 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, (UINT
)-1, NULL
);
467 /***********************************************************************
468 * RpcServerRegisterIfEx (RPCRT4.@)
470 RPC_STATUS WINAPI
RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
471 UINT Flags
, UINT MaxCalls
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
473 /* FIXME: Dump UUID using UuidToStringA */
474 TRACE( "(%p,%p,%p,%u,%u,%p)\n", IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, IfCallbackFn
);
476 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, (UINT
)-1, IfCallbackFn
);
479 /***********************************************************************
480 * RpcServerRegisterIf2 (RPCRT4.@)
482 RPC_STATUS WINAPI
RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
483 UINT Flags
, UINT MaxCalls
, UINT MaxRpcSize
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
485 /* FIXME: Dump UUID using UuidToStringA */
486 FIXME( "(%p,%p,%p,%u,%u,%u,%p): stub\n", IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, MaxRpcSize
, IfCallbackFn
);
488 return RPC_S_UNKNOWN_IF
; /* I guess this return code is as good as any failure */
492 /***********************************************************************
493 * RpcServerRegisterAuthInfoA (RPCRT4.@)
495 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoA( LPSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
498 FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName
, AuthnSvc
, GetKeyFn
, Arg
);
500 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
503 /***********************************************************************
504 * RpcServerRegisterAuthInfoW (RPCRT4.@)
506 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
509 FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName
), AuthnSvc
, GetKeyFn
, Arg
);
511 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
514 /***********************************************************************
515 * RpcServerListen (RPCRT4.@)
517 RPC_STATUS WINAPI
RpcServerListen( UINT MinimumCallThreads
, UINT MaxCalls
, UINT DontWait
)
519 FIXME( "(%u,%u,%u): stub\n", MinimumCallThreads
, MaxCalls
, DontWait
);
521 return RPC_S_NO_PROTSEQS_REGISTERED
; /* Since we don't allow registration this seems reasonable */
524 /***********************************************************************
525 * RpcStringBindingComposeA (RPCRT4.@)
527 RPC_STATUS WINAPI
RpcStringBindingComposeA( LPSTR ObjUuid
, LPSTR Protseq
, LPSTR NetworkAddr
, LPSTR Endpoint
,
528 LPSTR Options
, LPSTR
* StringBinding
)
530 FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
, StringBinding
);
531 *StringBinding
= NULL
;
533 return RPC_S_INVALID_STRING_UUID
; /* Failure */
536 /***********************************************************************
537 * RpcStringBindingComposeW (RPCRT4.@)
539 RPC_STATUS WINAPI
RpcStringBindingComposeW( LPWSTR ObjUuid
, LPWSTR Protseq
, LPWSTR NetworkAddr
, LPWSTR Endpoint
,
540 LPWSTR Options
, LPWSTR
* StringBinding
)
542 FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", debugstr_w( ObjUuid
), debugstr_w( Protseq
), debugstr_w( NetworkAddr
),
543 debugstr_w( Endpoint
), debugstr_w( Options
), StringBinding
);
544 *StringBinding
= NULL
;
546 return RPC_S_INVALID_STRING_UUID
; /* Failure */
549 /***********************************************************************
550 * RpcBindingFree (RPCRT4.@)
552 RPC_STATUS WINAPI
RpcBindingFree(RPC_BINDING_HANDLE
* Binding
)
554 FIXME("(%p): stub\n", Binding
);
557 /***********************************************************************
558 * RpcBindingFromStringBindingA (RPCRT4.@)
560 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( LPSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
562 FIXME( "(%s,%p): stub\n", StringBinding
, Binding
);
564 return RPC_S_INVALID_STRING_BINDING
; /* As good as any failure code */
567 /***********************************************************************
568 * RpcBindingFromStringBindingW (RPCRT4.@)
570 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( LPWSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
572 FIXME( "(%s,%p): stub\n", debugstr_w( StringBinding
), Binding
);
574 return RPC_S_INVALID_STRING_BINDING
; /* As good as any failure code */
577 /***********************************************************************
578 * NdrDllCanUnloadNow (RPCRT4.@)
580 HRESULT WINAPI
NdrDllCanUnloadNow(CStdPSFactoryBuffer
*pPSFactoryBuffer
)
582 FIXME("%p\n",pPSFactoryBuffer
);
586 /***********************************************************************
587 * NdrDllGetClassObject (RPCRT4.@)
589 HRESULT WINAPI
NdrDllGetClassObject(
590 REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
,
591 const ProxyFileInfo
** pProxyFileList
,
592 const CLSID
* pclsid
,
593 CStdPSFactoryBuffer
* pPSFactoryBuffer
)
597 return RPC_S_UNKNOWN_IF
;
600 /***********************************************************************
601 * DllRegisterServer (RPCRT4.@)
604 HRESULT WINAPI
RPCRT4_DllRegisterServer( void )
606 FIXME( "(): stub\n" );