📄 rpcrt4_main.c
字号:
sequence &= 0x1fff;
status = RPC_UuidGetNodeAddress(address);
initialised = 1;
}
/* Generate time element of the UUID. Account for going faster
than our clock as well as the clock going backwards. */
while (1) {
RPC_UuidGetSystemTime(&time);
if (time > timelast) {
count = 0;
break;
}
if (time < timelast) {
sequence = (sequence + 1) & 0x1fff;
count = 0;
break;
}
if (count < TICKS_PER_CLOCK_TICK) {
count++;
break;
}
}
timelast = time;
time += count;
/* Pack the information into the UUID structure. */
Uuid->Data1 = (unsigned long)(time & 0xffffffff);
Uuid->Data2 = (unsigned short)((time >> 32) & 0xffff);
Uuid->Data3 = (unsigned short)((time >> 48) & 0x0fff);
/* This is a version 1 UUID */
Uuid->Data3 |= (1 << 12);
Uuid->Data4[0] = sequence & 0xff;
Uuid->Data4[1] = (sequence & 0x3f00) >> 8;
Uuid->Data4[1] |= 0x80;
Uuid->Data4[2] = address[0];
Uuid->Data4[3] = address[1];
Uuid->Data4[4] = address[2];
Uuid->Data4[5] = address[3];
Uuid->Data4[6] = address[4];
Uuid->Data4[7] = address[5];
LeaveCriticalSection(&uuid_cs);
TRACE("%s\n", debugstr_guid(Uuid));
return status;
}
/*************************************************************************
* UuidCreateSequential [RPCRT4.@]
*
* Creates a 128bit UUID.
*
* RETURNS
*
* RPC_S_OK if successful.
* RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique.
*
*/
RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid)
{
return UuidCreate(Uuid);
}
/*************************************************************************
* UuidHash [RPCRT4.@]
*
* Generates a hash value for a given UUID
*
* Code based on FreeDCE implementation
*
*/
unsigned short WINAPI UuidHash(UUID *uuid, RPC_STATUS *Status)
{
BYTE *data = (BYTE*)uuid;
short c0 = 0, c1 = 0, x, y;
unsigned int i;
if (!uuid) data = (BYTE*)(uuid = &uuid_nil);
TRACE("(%s)\n", debugstr_guid(uuid));
for (i=0; i<sizeof(UUID); i++) {
c0 += data[i];
c1 += c0;
}
x = -c1 % 255;
if (x < 0) x += 255;
y = (c1 - c0) % 255;
if (y < 0) y += 255;
*Status = RPC_S_OK;
return y*256 + x;
}
/*************************************************************************
* UuidToStringA [RPCRT4.@]
*
* Converts a UUID to a string.
*
* UUID format is 8 hex digits, followed by a hyphen then three groups of
* 4 hex digits each followed by a hyphen and then 12 hex digits
*
* RETURNS
*
* S_OK if successful.
* S_OUT_OF_MEMORY if unsucessful.
*/
RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid)
{
*StringUuid = HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37);
if(!(*StringUuid))
return RPC_S_OUT_OF_MEMORY;
if (!Uuid) Uuid = &uuid_nil;
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],
Uuid->Data4[6], Uuid->Data4[7] );
return RPC_S_OK;
}
/*************************************************************************
* UuidToStringW [RPCRT4.@]
*
* Converts a UUID to a string.
*
* S_OK if successful.
* S_OUT_OF_MEMORY if unsucessful.
*/
RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, unsigned short** StringUuid)
{
char buf[37];
if (!Uuid) Uuid = &uuid_nil;
sprintf(buf, "%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],
Uuid->Data4[6], Uuid->Data4[7] );
*StringUuid = RPCRT4_strdupAtoW(buf);
if(!(*StringUuid))
return RPC_S_OUT_OF_MEMORY;
return RPC_S_OK;
}
static const BYTE hex2bin[] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x00 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x10 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x20 */
0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, /* 0x30 */
0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, /* 0x40 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x50 */
0,10,11,12,13,14,15 /* 0x60 */
};
/***********************************************************************
* UuidFromStringA (RPCRT4.@)
*/
RPC_STATUS WINAPI UuidFromStringA(unsigned char* s, UUID *uuid)
{
int i;
if (!s) return UuidCreateNil( 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;
for (i=0; i<36; i++)
{
if ((i == 8)||(i == 13)||(i == 18)||(i == 23)) continue;
if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0')) return RPC_S_INVALID_STRING_UUID;
}
/* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
uuid->Data1 = (hex2bin[s[0]] << 28 | hex2bin[s[1]] << 24 | hex2bin[s[2]] << 20 | hex2bin[s[3]] << 16 |
hex2bin[s[4]] << 12 | hex2bin[s[5]] << 8 | hex2bin[s[6]] << 4 | hex2bin[s[7]]);
uuid->Data2 = hex2bin[s[9]] << 12 | hex2bin[s[10]] << 8 | hex2bin[s[11]] << 4 | hex2bin[s[12]];
uuid->Data3 = hex2bin[s[14]] << 12 | hex2bin[s[15]] << 8 | hex2bin[s[16]] << 4 | hex2bin[s[17]];
/* these are just sequential bytes */
uuid->Data4[0] = hex2bin[s[19]] << 4 | hex2bin[s[20]];
uuid->Data4[1] = hex2bin[s[21]] << 4 | hex2bin[s[22]];
uuid->Data4[2] = hex2bin[s[24]] << 4 | hex2bin[s[25]];
uuid->Data4[3] = hex2bin[s[26]] << 4 | hex2bin[s[27]];
uuid->Data4[4] = hex2bin[s[28]] << 4 | hex2bin[s[29]];
uuid->Data4[5] = hex2bin[s[30]] << 4 | hex2bin[s[31]];
uuid->Data4[6] = hex2bin[s[32]] << 4 | hex2bin[s[33]];
uuid->Data4[7] = hex2bin[s[34]] << 4 | hex2bin[s[35]];
return RPC_S_OK;
}
/***********************************************************************
* UuidFromStringW (RPCRT4.@)
*/
RPC_STATUS WINAPI UuidFromStringW(unsigned short* s, UUID *uuid)
{
int i;
if (!s) return UuidCreateNil( uuid );
if (strlenW(s) != 36) return RPC_S_INVALID_STRING_UUID;
if ((s[8]!='-') || (s[13]!='-') || (s[18]!='-') || (s[23]!='-'))
return RPC_S_INVALID_STRING_UUID;
for (i=0; i<36; i++)
{
if ((i == 8)||(i == 13)||(i == 18)||(i == 23)) continue;
if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0')) return RPC_S_INVALID_STRING_UUID;
}
/* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
uuid->Data1 = (hex2bin[s[0]] << 28 | hex2bin[s[1]] << 24 | hex2bin[s[2]] << 20 | hex2bin[s[3]] << 16 |
hex2bin[s[4]] << 12 | hex2bin[s[5]] << 8 | hex2bin[s[6]] << 4 | hex2bin[s[7]]);
uuid->Data2 = hex2bin[s[9]] << 12 | hex2bin[s[10]] << 8 | hex2bin[s[11]] << 4 | hex2bin[s[12]];
uuid->Data3 = hex2bin[s[14]] << 12 | hex2bin[s[15]] << 8 | hex2bin[s[16]] << 4 | hex2bin[s[17]];
/* these are just sequential bytes */
uuid->Data4[0] = hex2bin[s[19]] << 4 | hex2bin[s[20]];
uuid->Data4[1] = hex2bin[s[21]] << 4 | hex2bin[s[22]];
uuid->Data4[2] = hex2bin[s[24]] << 4 | hex2bin[s[25]];
uuid->Data4[3] = hex2bin[s[26]] << 4 | hex2bin[s[27]];
uuid->Data4[4] = hex2bin[s[28]] << 4 | hex2bin[s[29]];
uuid->Data4[5] = hex2bin[s[30]] << 4 | hex2bin[s[31]];
uuid->Data4[6] = hex2bin[s[32]] << 4 | hex2bin[s[33]];
uuid->Data4[7] = hex2bin[s[34]] << 4 | hex2bin[s[35]];
return RPC_S_OK;
}
/***********************************************************************
* DllRegisterServer (RPCRT4.@)
*/
HRESULT WINAPI DllRegisterServer( void )
{
FIXME( "(): stub\n" );
return S_OK;
}
BOOL RPCRT4_StartRPCSS(void)
{
PROCESS_INFORMATION pi;
STARTUPINFOA si;
static char cmd[6];
BOOL rslt;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFOA));
si.cb = sizeof(STARTUPINFOA);
/* apparently it's not OK to use a constant string below */
CopyMemory(cmd, "rpcss", 6);
/* FIXME: will this do the right thing when run as a test? */
rslt = CreateProcessA(
NULL, /* executable */
cmd, /* command line */
NULL, /* process security attributes */
NULL, /* primary thread security attributes */
FALSE, /* inherit handles */
0, /* creation flags */
NULL, /* use parent's environment */
NULL, /* use parent's current directory */
&si, /* STARTUPINFO pointer */
&pi /* PROCESS_INFORMATION */
);
if (rslt) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
return rslt;
}
/***********************************************************************
* RPCRT4_RPCSSOnDemandCall (internal)
*
* Attempts to send a message to the RPCSS process
* on the local machine, invoking it if necessary.
* For remote RPCSS calls, use.... your imagination.
*
* PARAMS
* msg [I] pointer to the RPCSS message
* vardata_payload [I] pointer vardata portion of the RPCSS message
* reply [O] pointer to reply structure
*
* RETURNS
* TRUE if successful
* FALSE otherwise
*/
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply)
{
HANDLE client_handle;
int i, j = 0;
TRACE("(msg == %p, vardata_payload == %p, reply == %p)\n", msg, vardata_payload, reply);
client_handle = RPCRT4_RpcssNPConnect();
while (!client_handle) {
/* start the RPCSS process */
if (!RPCRT4_StartRPCSS()) {
ERR("Unable to start RPCSS process.\n");
return FALSE;
}
/* wait for a connection (w/ periodic polling) */
for (i = 0; i < 60; i++) {
Sleep(200);
client_handle = RPCRT4_RpcssNPConnect();
if (client_handle) break;
}
/* we are only willing to try twice */
if (j++ >= 1) break;
}
if (!client_handle) {
/* no dice! */
ERR("Unable to connect to RPCSS process!\n");
SetLastError(RPC_E_SERVER_DIED_DNE);
return FALSE;
}
/* great, we're connected. now send the message */
if (!RPCRT4_SendReceiveNPMsg(client_handle, msg, vardata_payload, reply)) {
ERR("Something is amiss: RPC_SendReceive failed.\n");
return FALSE;
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -