Sync to Wine-20050830:
[reactos.git] / reactos / lib / rpcrt4 / rpcrt4_main.c
index 15cbabc..354d0c3 100644 (file)
@@ -57,7 +57,7 @@
  *
  * - ORPC is RPC for OLE; once we have a working RPC framework, we can
  *   use it to implement out-of-process OLE client/server communications.
- *   ATM there is maybe a disconnect between the marshalling in the OLE DLL's
+ *   ATM there is maybe a disconnect between the marshalling in the OLE DLLs
  *   and the marshalling going on here [TODO: well, is there or not?]
  * 
  * - In-source API Documentation, at least for those functions which we have
 
 #include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
+WINE_DEFAULT_DEBUG_CHANNEL(rpc);
 
 static UUID uuid_nil;
 static HANDLE master_mutex;
@@ -152,8 +152,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls(hinstDLL);
         master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME);
-        if (!master_mutex)
-          ERR("Failed to create master mutex\n");
         break;
 
     case DLL_PROCESS_DETACH:
@@ -321,6 +319,8 @@ static void RPC_UuidGetSystemTime(ULONGLONG *time)
     *time += TICKS_15_OCT_1582_TO_1601;
 }
 
+typedef DWORD WINAPI (*LPGETADAPTERSINFO)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
+
 /* Assume that a hardware address is at least 6 bytes long */ 
 #define ADDRESS_BYTES_NEEDED 6
 
@@ -330,29 +330,47 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address)
     DWORD status = RPC_S_OK;
 
     ULONG buflen = sizeof(IP_ADAPTER_INFO);
-    PIP_ADAPTER_INFO adapter = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, buflen);
-
-    if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) {
-        HeapFree(GetProcessHeap(), 0, adapter);
-        adapter = (IP_ADAPTER_INFO *)HeapAlloc(GetProcessHeap(), 0, buflen);
-    }
-
-    if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) {
-        for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
-            address[i] = adapter->Address[i];
+    PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen);
+    HANDLE hIpHlpApi;
+    LPGETADAPTERSINFO pGetAdaptersInfo;
+    
+    hIpHlpApi = LoadLibrary("iphlpapi.dll");
+    if (hIpHlpApi)
+    {
+        pGetAdaptersInfo = (LPGETADAPTERSINFO)GetProcAddress(hIpHlpApi, "GetAdaptersInfo");
+        if (pGetAdaptersInfo)
+        {
+            if (pGetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) {
+                HeapFree(GetProcessHeap(), 0, adapter);
+                adapter = HeapAlloc(GetProcessHeap(), 0, buflen);
+            }
+
+            if (pGetAdaptersInfo(adapter, &buflen) == NO_ERROR) {
+                for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
+                    address[i] = adapter->Address[i];
+                }
+            }
+            else
+            {
+                goto local;
+            }   
         }
+        
+        /* Free the Library */
+        FreeLibrary(hIpHlpApi);
+        goto exit;
     }
+     
+local:   
     /* We can't get a hardware address, just use random numbers.
-       Set the multicast bit to prevent conflicts with real cards. */
-    else {
-        for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
-            address[i] = rand() & 0xff;
-        }
-
-        address[0] |= 0x80;
-        status = RPC_S_UUID_LOCAL_ONLY;
+        Set the multicast bit to prevent conflicts with real cards. */
+    for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) {
+        address[i] = rand() & 0xff;
     }
-
+    address[0] |= 0x01;
+    status = RPC_S_UUID_LOCAL_ONLY;
+    
+exit:
     HeapFree(GetProcessHeap(), 0, adapter);
     return status;
 }
@@ -475,7 +493,7 @@ unsigned short WINAPI UuidHash(UUID *uuid, RPC_STATUS *Status)
 {
   BYTE *data = (BYTE*)uuid;
   short c0 = 0, c1 = 0, x, y;
-  int i;
+  unsigned int i;
 
   if (!uuid) data = (BYTE*)(uuid = &uuid_nil);
 
@@ -518,7 +536,7 @@ RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid)
 
   if (!Uuid) Uuid = &uuid_nil;
 
-  sprintf(*StringUuid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+  sprintf( (char*)*StringUuid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                  Uuid->Data1, Uuid->Data2, Uuid->Data3,
                  Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2],
                  Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5],
@@ -569,14 +587,13 @@ static const BYTE hex2bin[] =
 /***********************************************************************
  *             UuidFromStringA (RPCRT4.@)
  */
-RPC_STATUS WINAPI UuidFromStringA(unsigned char* str, UUID *uuid)
+RPC_STATUS WINAPI UuidFromStringA(unsigned char* s, UUID *uuid)
 {
-    BYTE *s = (BYTE *)str;
     int i;
 
     if (!s) return UuidCreateNil( uuid );
 
-    if (strlen(s) != 36) return RPC_S_INVALID_STRING_UUID;
+    if (strlen((char*)s) != 36) return RPC_S_INVALID_STRING_UUID;
 
     if ((s[8]!='-') || (s[13]!='-') || (s[18]!='-') || (s[23]!='-'))
         return RPC_S_INVALID_STRING_UUID;
@@ -650,7 +667,7 @@ RPC_STATUS WINAPI UuidFromStringW(unsigned short* s, UUID *uuid)
  *              DllRegisterServer (RPCRT4.@)
  */
 
-HRESULT WINAPI RPCRT4_DllRegisterServer( void )
+HRESULT WINAPI DllRegisterServer( void )
 {
     FIXME( "(): stub\n" );
     return S_OK;
@@ -748,3 +765,56 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
 
     return TRUE;
 }
+
+#define MAX_RPC_ERROR_TEXT 256
+
+/******************************************************************************
+ * DceErrorInqTextW   (rpcrt4.@)
+ *
+ * Notes
+ * 1. On passing a NULL pointer the code does bomb out.
+ * 2. The size of the required buffer is not defined in the documentation.
+ *    It appears to be 256.
+ * 3. The function is defined to return RPC_S_INVALID_ARG but I don't know
+ *    of any value for which it does.
+ * 4. The MSDN documentation currently declares that the second argument is
+ *    unsigned char *, even for the W version.  I don't believe it.
+ */
+RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, unsigned short *buffer)
+{
+    DWORD count;
+    count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
+                FORMAT_MESSAGE_IGNORE_INSERTS,
+                NULL, e, 0, buffer, MAX_RPC_ERROR_TEXT, NULL);
+    if (!count)
+    {
+        count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
+                FORMAT_MESSAGE_IGNORE_INSERTS,
+                NULL, RPC_S_NOT_RPC_ERROR, 0, buffer, MAX_RPC_ERROR_TEXT, NULL);
+        if (!count)
+        {
+            ERR ("Failed to translate error");
+            return RPC_S_INVALID_ARG;
+        }
+    }
+    return RPC_S_OK;
+}
+
+/******************************************************************************
+ * DceErrorInqTextA   (rpcrt4.@)
+ */
+RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, unsigned char *buffer)
+{
+    RPC_STATUS status;
+    WCHAR bufferW [MAX_RPC_ERROR_TEXT];
+    if ((status = DceErrorInqTextW (e, bufferW)) == RPC_S_OK)
+    {
+        if (!WideCharToMultiByte(CP_ACP, 0, bufferW, -1, (LPSTR)buffer, MAX_RPC_ERROR_TEXT,
+                NULL, NULL))
+        {
+            ERR ("Failed to translate error");
+            status = RPC_S_INVALID_ARG;
+        }
+    }
+    return status;
+}