ole32: Implement SNB marshalling.
This commit is contained in:
parent
04ed24fb79
commit
aa3a234803
@ -768,6 +768,99 @@ static void test_marshal_STGMEDIUM(void)
|
|||||||
HeapFree(GetProcessHeap(), 0, expect_buffer);
|
HeapFree(GetProcessHeap(), 0, expect_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_marshal_SNB(void)
|
||||||
|
{
|
||||||
|
static const WCHAR str1W[] = {'s','t','r','i','n','g','1',0};
|
||||||
|
static const WCHAR str2W[] = {'s','t','r','2',0};
|
||||||
|
unsigned char *buffer, *src, *mbuf;
|
||||||
|
MIDL_STUB_MESSAGE stub_msg;
|
||||||
|
WCHAR **ptrW, *dataW;
|
||||||
|
USER_MARSHAL_CB umcb;
|
||||||
|
RPC_MESSAGE rpc_msg;
|
||||||
|
RemSNB *wiresnb;
|
||||||
|
SNB snb, snb2;
|
||||||
|
ULONG size;
|
||||||
|
|
||||||
|
/* 4 bytes alignment */
|
||||||
|
snb = NULL;
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||||
|
size = SNB_UserSize(&umcb.Flags, 3, &snb);
|
||||||
|
ok(size == 16, "Size should be 16, instead of %d\n", size);
|
||||||
|
|
||||||
|
/* NULL block */
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||||
|
size = SNB_UserSize(&umcb.Flags, 0, &snb);
|
||||||
|
ok(size == 12, "Size should be 12, instead of %d\n", size);
|
||||||
|
|
||||||
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||||
|
mbuf = SNB_UserMarshal(&umcb.Flags, buffer, &snb);
|
||||||
|
ok(mbuf == buffer + size, "got %p, %p\n", mbuf, buffer + size);
|
||||||
|
|
||||||
|
wiresnb = (RemSNB*)buffer;
|
||||||
|
ok(wiresnb->ulCntStr == 0, "got %u\n", wiresnb->ulCntStr);
|
||||||
|
ok(wiresnb->ulCntChar == 0, "got %u\n", wiresnb->ulCntChar);
|
||||||
|
ok(*(ULONG*)wiresnb->rgString == 0, "got %u\n", *(ULONG*)wiresnb->rgString);
|
||||||
|
|
||||||
|
snb2 = NULL;
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||||
|
SNB_UserUnmarshal(&umcb.Flags, buffer, &snb2);
|
||||||
|
ok(snb2 == NULL, "got %p\n", snb2);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||||
|
SNB_UserFree(&umcb.Flags, &snb2);
|
||||||
|
|
||||||
|
/* block with actual data */
|
||||||
|
|
||||||
|
/* allocate source block, n+1 pointers first, then data */
|
||||||
|
src = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR*)*3 + sizeof(str1W) + sizeof(str2W));
|
||||||
|
ptrW = (WCHAR**)src;
|
||||||
|
dataW = *ptrW = (WCHAR*)(src + 3*sizeof(WCHAR*));
|
||||||
|
ptrW++;
|
||||||
|
*ptrW = (WCHAR*)(src + 3*sizeof(WCHAR*) + sizeof(str1W));
|
||||||
|
ptrW++;
|
||||||
|
*ptrW = NULL;
|
||||||
|
lstrcpyW(dataW, str1W);
|
||||||
|
dataW += lstrlenW(str1W) + 1;
|
||||||
|
lstrcpyW(dataW, str2W);
|
||||||
|
|
||||||
|
snb = (SNB)src;
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||||
|
size = SNB_UserSize(&umcb.Flags, 0, &snb);
|
||||||
|
ok(size == 38, "Size should be 38, instead of %d\n", size);
|
||||||
|
|
||||||
|
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||||
|
SNB_UserMarshal(&umcb.Flags, buffer, &snb);
|
||||||
|
|
||||||
|
wiresnb = (RemSNB*)buffer;
|
||||||
|
ok(wiresnb->ulCntStr == 13, "got %u\n", wiresnb->ulCntStr);
|
||||||
|
ok(wiresnb->ulCntChar == 2, "got %u\n", wiresnb->ulCntChar);
|
||||||
|
/* payload length is stored one more time, as ULONG */
|
||||||
|
ok(*(ULONG*)wiresnb->rgString == wiresnb->ulCntStr, "got %u\n", *(ULONG*)wiresnb->rgString);
|
||||||
|
dataW = &wiresnb->rgString[2];
|
||||||
|
ok(!lstrcmpW(dataW, str1W), "marshalled string 0: %s\n", wine_dbgstr_w(dataW));
|
||||||
|
dataW += sizeof(str1W)/sizeof(WCHAR);
|
||||||
|
ok(!lstrcmpW(dataW, str2W), "marshalled string 1: %s\n", wine_dbgstr_w(dataW));
|
||||||
|
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||||
|
|
||||||
|
snb2 = NULL;
|
||||||
|
SNB_UserUnmarshal(&umcb.Flags, buffer, &snb2);
|
||||||
|
|
||||||
|
ptrW = snb2;
|
||||||
|
ok(!lstrcmpW(*ptrW, str1W), "unmarshalled string 0: %s\n", wine_dbgstr_w(*ptrW));
|
||||||
|
ptrW++;
|
||||||
|
ok(!lstrcmpW(*ptrW, str2W), "unmarshalled string 1: %s\n", wine_dbgstr_w(*ptrW));
|
||||||
|
ptrW++;
|
||||||
|
ok(*ptrW == NULL, "expected terminating NULL ptr, got %p, start %p\n", *ptrW, snb2);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
|
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||||
|
SNB_UserFree(&umcb.Flags, &snb2);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(usrmarshal)
|
START_TEST(usrmarshal)
|
||||||
{
|
{
|
||||||
CoInitialize(NULL);
|
CoInitialize(NULL);
|
||||||
@ -780,6 +873,7 @@ START_TEST(usrmarshal)
|
|||||||
test_marshal_HMETAFILEPICT();
|
test_marshal_HMETAFILEPICT();
|
||||||
test_marshal_WdtpInterfacePointer();
|
test_marshal_WdtpInterfacePointer();
|
||||||
test_marshal_STGMEDIUM();
|
test_marshal_STGMEDIUM();
|
||||||
|
test_marshal_SNB();
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
@ -2160,25 +2160,117 @@ void __RPC_USER FLAG_STGMEDIUM_UserFree(ULONG *pFlags, FLAG_STGMEDIUM *pStgMediu
|
|||||||
|
|
||||||
ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
|
ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
|
||||||
{
|
{
|
||||||
FIXME(":stub\n");
|
ULONG size = StartingSize;
|
||||||
return StartingSize;
|
|
||||||
|
TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pSnb);
|
||||||
|
|
||||||
|
ALIGN_LENGTH(size, 3);
|
||||||
|
|
||||||
|
/* two counters from RemSNB header, plus one more ULONG */
|
||||||
|
size += 3*sizeof(ULONG);
|
||||||
|
|
||||||
|
/* now actual data length */
|
||||||
|
if (*pSnb)
|
||||||
|
{
|
||||||
|
WCHAR **ptrW = *pSnb;
|
||||||
|
|
||||||
|
while (*ptrW)
|
||||||
|
{
|
||||||
|
size += (strlenW(*ptrW) + 1)*sizeof(WCHAR);
|
||||||
|
ptrW++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SNB_wire {
|
||||||
|
ULONG charcnt;
|
||||||
|
ULONG strcnt;
|
||||||
|
ULONG datalen;
|
||||||
|
WCHAR data[1];
|
||||||
|
};
|
||||||
|
|
||||||
unsigned char * __RPC_USER SNB_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
|
unsigned char * __RPC_USER SNB_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
|
||||||
{
|
{
|
||||||
FIXME(":stub\n");
|
struct SNB_wire *wire;
|
||||||
return pBuffer;
|
ULONG size;
|
||||||
|
|
||||||
|
TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, pSnb);
|
||||||
|
|
||||||
|
ALIGN_POINTER(pBuffer, 3);
|
||||||
|
|
||||||
|
wire = (struct SNB_wire*)pBuffer;
|
||||||
|
wire->charcnt = wire->strcnt = 0;
|
||||||
|
size = 3*sizeof(ULONG);
|
||||||
|
|
||||||
|
if (*pSnb)
|
||||||
|
{
|
||||||
|
WCHAR **ptrW = *pSnb;
|
||||||
|
WCHAR *dataW = wire->data;
|
||||||
|
|
||||||
|
while (*ptrW)
|
||||||
|
{
|
||||||
|
ULONG len = strlenW(*ptrW) + 1;
|
||||||
|
|
||||||
|
wire->strcnt++;
|
||||||
|
wire->charcnt += len;
|
||||||
|
memcpy(dataW, *ptrW, len*sizeof(WCHAR));
|
||||||
|
dataW += len;
|
||||||
|
|
||||||
|
size += len*sizeof(WCHAR);
|
||||||
|
ptrW++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wire->datalen = wire->charcnt;
|
||||||
|
return pBuffer + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char * __RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
|
unsigned char * __RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
|
||||||
{
|
{
|
||||||
FIXME(":stub\n");
|
USER_MARSHAL_CB *umcb = (USER_MARSHAL_CB*)pFlags;
|
||||||
return pBuffer;
|
struct SNB_wire *wire;
|
||||||
|
|
||||||
|
TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, pSnb);
|
||||||
|
|
||||||
|
wire = (struct SNB_wire*)pBuffer;
|
||||||
|
|
||||||
|
if (*pSnb)
|
||||||
|
umcb->pStubMsg->pfnFree(*pSnb);
|
||||||
|
|
||||||
|
if (wire->datalen == 0)
|
||||||
|
*pSnb = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WCHAR *src = wire->data, *dest;
|
||||||
|
WCHAR **ptrW;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
ptrW = *pSnb = umcb->pStubMsg->pfnAllocate((wire->strcnt+1)*sizeof(WCHAR*) + wire->datalen);
|
||||||
|
dest = (WCHAR*)(*pSnb + wire->strcnt + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < wire->strcnt; i++)
|
||||||
|
{
|
||||||
|
ULONG len = strlenW(src);
|
||||||
|
memcpy(dest, src, (len + 1)*sizeof(WCHAR));
|
||||||
|
*ptrW = dest;
|
||||||
|
src += len + 1;
|
||||||
|
dest += len + 1;
|
||||||
|
ptrW++;
|
||||||
|
}
|
||||||
|
*ptrW = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBuffer + 3*sizeof(ULONG) + wire->datalen*sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)
|
void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)
|
||||||
{
|
{
|
||||||
FIXME(":stub\n");
|
USER_MARSHAL_CB *umcb = (USER_MARSHAL_CB*)pFlags;
|
||||||
|
TRACE("(%p)\n", pSnb);
|
||||||
|
if (*pSnb)
|
||||||
|
umcb->pStubMsg->pfnFree(*pSnb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call_as/local stubs for unknwn.idl */
|
/* call_as/local stubs for unknwn.idl */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user