mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
add some of the shlwapi tests
svn path=/trunk/; revision=17126
This commit is contained in:
parent
bf046096f1
commit
d8de9b24fb
10 changed files with 3280 additions and 0 deletions
9
reactos/regtests/winetests/shlwapi/.cvsignore
Executable file
9
reactos/regtests/winetests/shlwapi/.cvsignore
Executable file
|
@ -0,0 +1,9 @@
|
|||
Makefile
|
||||
clist.ok
|
||||
clsid.ok
|
||||
generated.ok
|
||||
ordinal.ok
|
||||
path.ok
|
||||
shreg.ok
|
||||
string.ok
|
||||
testlist.c
|
643
reactos/regtests/winetests/shlwapi/clist.c
Executable file
643
reactos/regtests/winetests/shlwapi/clist.c
Executable file
|
@ -0,0 +1,643 @@
|
|||
/* Unit test suite for SHLWAPI Compact List and IStream ordinal functions
|
||||
*
|
||||
* Copyright 2002 Jon Griffiths
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
typedef struct tagSHLWAPI_CLIST
|
||||
{
|
||||
ULONG ulSize;
|
||||
ULONG ulId;
|
||||
} SHLWAPI_CLIST, *LPSHLWAPI_CLIST;
|
||||
|
||||
typedef const SHLWAPI_CLIST* LPCSHLWAPI_CLIST;
|
||||
|
||||
/* Items to add */
|
||||
static const SHLWAPI_CLIST SHLWAPI_CLIST_items[] =
|
||||
{
|
||||
{4, 1},
|
||||
{8, 3},
|
||||
{12, 2},
|
||||
{16, 8},
|
||||
{20, 9},
|
||||
{3, 11},
|
||||
{9, 82},
|
||||
{33, 16},
|
||||
{32, 55},
|
||||
{24, 100},
|
||||
{39, 116},
|
||||
{ 0, 0}
|
||||
};
|
||||
|
||||
/* Dummy IStream object for testing calls */
|
||||
typedef struct
|
||||
{
|
||||
void* lpVtbl;
|
||||
LONG ref;
|
||||
int readcalls;
|
||||
BOOL failreadcall;
|
||||
BOOL failreadsize;
|
||||
BOOL readbeyondend;
|
||||
BOOL readreturnlarge;
|
||||
int writecalls;
|
||||
BOOL failwritecall;
|
||||
BOOL failwritesize;
|
||||
int seekcalls;
|
||||
int statcalls;
|
||||
BOOL failstatcall;
|
||||
LPCSHLWAPI_CLIST item;
|
||||
ULARGE_INTEGER pos;
|
||||
} _IDummyStream;
|
||||
|
||||
static
|
||||
HRESULT WINAPI QueryInterface(_IDummyStream *This,REFIID riid, LPVOID *ppvObj)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI AddRef(_IDummyStream *This)
|
||||
{
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI Release(_IDummyStream *This)
|
||||
{
|
||||
return InterlockedDecrement(&This->ref);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Read(_IDummyStream* This, LPVOID lpMem, ULONG ulSize,
|
||||
PULONG lpRead)
|
||||
{
|
||||
HRESULT hRet = S_OK;
|
||||
++This->readcalls;
|
||||
|
||||
if (This->failreadcall)
|
||||
{
|
||||
return STG_E_ACCESSDENIED;
|
||||
}
|
||||
else if (This->failreadsize)
|
||||
{
|
||||
*lpRead = ulSize + 8;
|
||||
return S_OK;
|
||||
}
|
||||
else if (This->readreturnlarge)
|
||||
{
|
||||
*((ULONG*)lpMem) = 0xffff01;
|
||||
*lpRead = ulSize;
|
||||
This->readreturnlarge = FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
if (ulSize == sizeof(ULONG))
|
||||
{
|
||||
/* Read size of item */
|
||||
*((ULONG*)lpMem) = This->item->ulSize ? This->item->ulSize + sizeof(SHLWAPI_CLIST) : 0;
|
||||
*lpRead = ulSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i;
|
||||
char* buff = (char*)lpMem;
|
||||
|
||||
/* Read item data */
|
||||
if (!This->item->ulSize)
|
||||
{
|
||||
This->readbeyondend = TRUE;
|
||||
*lpRead = 0;
|
||||
return E_FAIL; /* Should never happen */
|
||||
}
|
||||
*((ULONG*)lpMem) = This->item->ulId;
|
||||
*lpRead = ulSize;
|
||||
|
||||
for (i = 0; i < This->item->ulSize; i++)
|
||||
buff[4+i] = i*2;
|
||||
|
||||
This->item++;
|
||||
}
|
||||
return hRet;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Write(_IDummyStream* This, LPVOID lpMem, ULONG ulSize,
|
||||
PULONG lpWritten)
|
||||
{
|
||||
HRESULT hRet = S_OK;
|
||||
|
||||
++This->writecalls;
|
||||
if (This->failwritecall)
|
||||
{
|
||||
return STG_E_ACCESSDENIED;
|
||||
}
|
||||
else if (This->failwritesize)
|
||||
{
|
||||
*lpWritten = 0;
|
||||
}
|
||||
else
|
||||
*lpWritten = ulSize;
|
||||
return hRet;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Seek(_IDummyStream* This, LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
|
||||
{
|
||||
++This->seekcalls;
|
||||
This->pos.QuadPart = dlibMove.QuadPart;
|
||||
if (plibNewPosition)
|
||||
plibNewPosition->QuadPart = dlibMove.QuadPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Stat(_IDummyStream* This, STATSTG* pstatstg,
|
||||
DWORD grfStatFlag)
|
||||
{
|
||||
++This->statcalls;
|
||||
if (This->failstatcall)
|
||||
return E_FAIL;
|
||||
if (pstatstg)
|
||||
pstatstg->cbSize.QuadPart = This->pos.QuadPart;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* VTable */
|
||||
static void* iclvt[] =
|
||||
{
|
||||
QueryInterface,
|
||||
AddRef,
|
||||
Release,
|
||||
Read,
|
||||
Write,
|
||||
Seek,
|
||||
NULL, /* SetSize */
|
||||
NULL, /* CopyTo */
|
||||
NULL, /* Commit */
|
||||
NULL, /* Revert */
|
||||
NULL, /* LockRegion */
|
||||
NULL, /* UnlockRegion */
|
||||
Stat,
|
||||
NULL /* Clone */
|
||||
};
|
||||
|
||||
/* Function ptrs for ordinal calls */
|
||||
static HMODULE SHLWAPI_hshlwapi = 0;
|
||||
|
||||
static VOID (WINAPI *pSHLWAPI_19)(LPSHLWAPI_CLIST);
|
||||
static HRESULT (WINAPI *pSHLWAPI_20)(LPSHLWAPI_CLIST*,LPCSHLWAPI_CLIST);
|
||||
static BOOL (WINAPI *pSHLWAPI_21)(LPSHLWAPI_CLIST*,ULONG);
|
||||
static LPSHLWAPI_CLIST (WINAPI *pSHLWAPI_22)(LPSHLWAPI_CLIST,ULONG);
|
||||
static HRESULT (WINAPI *pSHLWAPI_17)(_IDummyStream*,LPSHLWAPI_CLIST);
|
||||
static HRESULT (WINAPI *pSHLWAPI_18)(_IDummyStream*,LPSHLWAPI_CLIST*);
|
||||
|
||||
static BOOL (WINAPI *pSHLWAPI_166)(_IDummyStream*);
|
||||
static HRESULT (WINAPI *pSHLWAPI_184)(_IDummyStream*,LPVOID,ULONG);
|
||||
static HRESULT (WINAPI *pSHLWAPI_212)(_IDummyStream*,LPCVOID,ULONG);
|
||||
static HRESULT (WINAPI *pSHLWAPI_213)(_IDummyStream*);
|
||||
static HRESULT (WINAPI *pSHLWAPI_214)(_IDummyStream*,ULARGE_INTEGER*);
|
||||
|
||||
|
||||
static void InitFunctionPtrs(void)
|
||||
{
|
||||
SHLWAPI_hshlwapi = LoadLibraryA("shlwapi.dll");
|
||||
ok(SHLWAPI_hshlwapi != 0, "LoadLibrary failed\n");
|
||||
if (SHLWAPI_hshlwapi)
|
||||
{
|
||||
pSHLWAPI_17 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17);
|
||||
ok(pSHLWAPI_17 != 0, "No Ordinal 17\n");
|
||||
pSHLWAPI_18 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18);
|
||||
ok(pSHLWAPI_18 != 0, "No Ordinal 18\n");
|
||||
pSHLWAPI_19 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19);
|
||||
ok(pSHLWAPI_19 != 0, "No Ordinal 19\n");
|
||||
pSHLWAPI_20 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20);
|
||||
ok(pSHLWAPI_20 != 0, "No Ordinal 20\n");
|
||||
pSHLWAPI_21 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21);
|
||||
ok(pSHLWAPI_21 != 0, "No Ordinal 21\n");
|
||||
pSHLWAPI_22 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22);
|
||||
ok(pSHLWAPI_22 != 0, "No Ordinal 22\n");
|
||||
pSHLWAPI_166 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166);
|
||||
ok(pSHLWAPI_166 != 0, "No Ordinal 166\n");
|
||||
pSHLWAPI_184 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184);
|
||||
ok(pSHLWAPI_184 != 0, "No Ordinal 184\n");
|
||||
pSHLWAPI_212 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212);
|
||||
ok(pSHLWAPI_212 != 0, "No Ordinal 212\n");
|
||||
pSHLWAPI_213 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213);
|
||||
ok(pSHLWAPI_213 != 0, "No Ordinal 213\n");
|
||||
pSHLWAPI_214 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214);
|
||||
ok(pSHLWAPI_214 != 0, "No Ordinal 214\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void InitDummyStream(_IDummyStream* iface)
|
||||
{
|
||||
iface->lpVtbl = (void*)iclvt;
|
||||
iface->ref = 1;
|
||||
iface->readcalls = 0;
|
||||
iface->failreadcall = FALSE;
|
||||
iface->failreadsize = FALSE;
|
||||
iface->readbeyondend = FALSE;
|
||||
iface->readreturnlarge = FALSE;
|
||||
iface->writecalls = 0;
|
||||
iface->failwritecall = FALSE;
|
||||
iface->failwritesize = FALSE;
|
||||
iface->seekcalls = 0;
|
||||
iface->statcalls = 0;
|
||||
iface->failstatcall = FALSE;
|
||||
iface->item = SHLWAPI_CLIST_items;
|
||||
iface->pos.QuadPart = 0;
|
||||
}
|
||||
|
||||
|
||||
static void test_CList(void)
|
||||
{
|
||||
_IDummyStream streamobj;
|
||||
LPSHLWAPI_CLIST list = NULL;
|
||||
LPCSHLWAPI_CLIST item = SHLWAPI_CLIST_items;
|
||||
HRESULT hRet;
|
||||
LPSHLWAPI_CLIST inserted;
|
||||
BYTE buff[64];
|
||||
unsigned int i;
|
||||
|
||||
if (!pSHLWAPI_17 || !pSHLWAPI_18 || !pSHLWAPI_19 || !pSHLWAPI_20 ||
|
||||
!pSHLWAPI_21 || !pSHLWAPI_22)
|
||||
return;
|
||||
|
||||
/* Populate a list and test the items are added correctly */
|
||||
while (item->ulSize)
|
||||
{
|
||||
/* Create item and fill with data */
|
||||
inserted = (LPSHLWAPI_CLIST)buff;
|
||||
inserted->ulSize = item->ulSize + sizeof(SHLWAPI_CLIST);
|
||||
inserted->ulId = item->ulId;
|
||||
for (i = 0; i < item->ulSize; i++)
|
||||
buff[sizeof(SHLWAPI_CLIST)+i] = i*2;
|
||||
|
||||
/* Add it */
|
||||
hRet = pSHLWAPI_20(&list, inserted);
|
||||
ok(hRet > S_OK, "failed list add\n");
|
||||
|
||||
if (hRet > S_OK)
|
||||
{
|
||||
ok(list && list->ulSize, "item not added\n");
|
||||
|
||||
/* Find it */
|
||||
inserted = pSHLWAPI_22(list, item->ulId);
|
||||
ok(inserted != NULL, "lost after adding\n");
|
||||
|
||||
ok(!inserted || inserted->ulId != ~0UL, "find returned a container\n");
|
||||
|
||||
/* Check size */
|
||||
if (inserted && inserted->ulSize & 0x3)
|
||||
{
|
||||
/* Contained */
|
||||
ok(inserted[-1].ulId == ~0UL, "invalid size is not countained\n");
|
||||
ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST),
|
||||
"container too small\n");
|
||||
}
|
||||
else if (inserted)
|
||||
{
|
||||
ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST),
|
||||
"id %ld size wrong (%ld!=%ld)\n", inserted->ulId, inserted->ulSize,
|
||||
item->ulSize+sizeof(SHLWAPI_CLIST));
|
||||
}
|
||||
if (inserted)
|
||||
{
|
||||
BOOL bDataOK = TRUE;
|
||||
LPBYTE bufftest = (LPBYTE)inserted;
|
||||
|
||||
for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++)
|
||||
if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2)
|
||||
bDataOK = FALSE;
|
||||
|
||||
ok(bDataOK == TRUE, "data corrupted on insert\n");
|
||||
}
|
||||
ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n");
|
||||
}
|
||||
item++;
|
||||
}
|
||||
|
||||
/* Write the list */
|
||||
InitDummyStream(&streamobj);
|
||||
|
||||
hRet = pSHLWAPI_17(&streamobj, list);
|
||||
ok(hRet == S_OK, "write failed\n");
|
||||
if (hRet == S_OK)
|
||||
{
|
||||
/* 1 call for each element, + 1 for OK (use our null element for this) */
|
||||
ok(streamobj.writecalls == sizeof(SHLWAPI_CLIST_items)/sizeof(SHLWAPI_CLIST),
|
||||
"wrong call count\n");
|
||||
ok(streamobj.readcalls == 0,"called Read() in write\n");
|
||||
ok(streamobj.seekcalls == 0,"called Seek() in write\n");
|
||||
}
|
||||
|
||||
/* Failure cases for writing */
|
||||
InitDummyStream(&streamobj);
|
||||
streamobj.failwritecall = TRUE;
|
||||
hRet = pSHLWAPI_17(&streamobj, list);
|
||||
ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n");
|
||||
ok(streamobj.writecalls == 1, "called object after failure\n");
|
||||
ok(streamobj.readcalls == 0,"called Read() after failure\n");
|
||||
ok(streamobj.seekcalls == 0,"called Seek() after failure\n");
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
streamobj.failwritesize = TRUE;
|
||||
hRet = pSHLWAPI_17(&streamobj, list);
|
||||
ok(hRet == STG_E_MEDIUMFULL, "changed size failure return\n");
|
||||
ok(streamobj.writecalls == 1, "called object after size failure\n");
|
||||
ok(streamobj.readcalls == 0,"called Read() after failure\n");
|
||||
ok(streamobj.seekcalls == 0,"called Seek() after failure\n");
|
||||
|
||||
/* Invalid inputs for adding */
|
||||
inserted = (LPSHLWAPI_CLIST)buff;
|
||||
inserted->ulSize = sizeof(SHLWAPI_CLIST) -1;
|
||||
inserted->ulId = 33;
|
||||
hRet = pSHLWAPI_20(&list, inserted);
|
||||
/* The call succeeds but the item is not inserted, except on some early
|
||||
* versions which return failure. Wine behaves like later versions.
|
||||
*/
|
||||
#if 0
|
||||
ok(hRet == S_OK, "failed bad element size\n");
|
||||
#endif
|
||||
inserted = pSHLWAPI_22(list, 33);
|
||||
ok(inserted == NULL, "inserted bad element size\n");
|
||||
|
||||
inserted = (LPSHLWAPI_CLIST)buff;
|
||||
inserted->ulSize = 44;
|
||||
inserted->ulId = ~0UL;
|
||||
hRet = pSHLWAPI_20(&list, inserted);
|
||||
/* See comment above, some early versions fail this call */
|
||||
#if 0
|
||||
ok(hRet == S_OK, "failed adding a container\n");
|
||||
#endif
|
||||
item = SHLWAPI_CLIST_items;
|
||||
|
||||
/* Look for nonexistent item in populated list */
|
||||
inserted = pSHLWAPI_22(list, 99999999);
|
||||
ok(inserted == NULL, "found a nonexistent item\n");
|
||||
|
||||
while (item->ulSize)
|
||||
{
|
||||
/* Delete items */
|
||||
BOOL bRet = pSHLWAPI_21(&list, item->ulId);
|
||||
ok(bRet == TRUE, "couldn't find item to delete\n");
|
||||
item++;
|
||||
}
|
||||
|
||||
/* Look for nonexistent item in empty list */
|
||||
inserted = pSHLWAPI_22(list, 99999999);
|
||||
ok(inserted == NULL, "found an item in empty list\n");
|
||||
|
||||
/* Create a list by reading in data */
|
||||
InitDummyStream(&streamobj);
|
||||
|
||||
hRet = pSHLWAPI_18(&streamobj, &list);
|
||||
ok(hRet == S_OK, "failed create from Read()\n");
|
||||
if (hRet == S_OK)
|
||||
{
|
||||
ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
|
||||
/* 2 calls per item, but only 1 for the terminator */
|
||||
ok(streamobj.readcalls == sizeof(SHLWAPI_CLIST_items)/sizeof(SHLWAPI_CLIST)*2-1,
|
||||
"wrong call count\n");
|
||||
ok(streamobj.writecalls == 0, "called Write() from create\n");
|
||||
ok(streamobj.seekcalls == 0,"called Seek() from create\n");
|
||||
|
||||
item = SHLWAPI_CLIST_items;
|
||||
|
||||
/* Check the items were added correctly */
|
||||
while (item->ulSize)
|
||||
{
|
||||
inserted = pSHLWAPI_22(list, item->ulId);
|
||||
ok(inserted != NULL, "lost after adding\n");
|
||||
|
||||
ok(!inserted || inserted->ulId != ~0UL, "find returned a container\n");
|
||||
|
||||
/* Check size */
|
||||
if (inserted && inserted->ulSize & 0x3)
|
||||
{
|
||||
/* Contained */
|
||||
ok(inserted[-1].ulId == ~0UL, "invalid size is not countained\n");
|
||||
ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST),
|
||||
"container too small\n");
|
||||
}
|
||||
else if (inserted)
|
||||
{
|
||||
ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST),
|
||||
"id %ld size wrong (%ld!=%ld)\n", inserted->ulId, inserted->ulSize,
|
||||
item->ulSize+sizeof(SHLWAPI_CLIST));
|
||||
}
|
||||
ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n");
|
||||
if (inserted)
|
||||
{
|
||||
BOOL bDataOK = TRUE;
|
||||
LPBYTE bufftest = (LPBYTE)inserted;
|
||||
|
||||
for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++)
|
||||
if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2)
|
||||
bDataOK = FALSE;
|
||||
|
||||
ok(bDataOK == TRUE, "data corrupted on insert\n");
|
||||
}
|
||||
item++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Failure cases for reading */
|
||||
InitDummyStream(&streamobj);
|
||||
streamobj.failreadcall = TRUE;
|
||||
hRet = pSHLWAPI_18(&streamobj, &list);
|
||||
ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n");
|
||||
ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
|
||||
ok(streamobj.readcalls == 1, "called object after read failure\n");
|
||||
ok(streamobj.writecalls == 0,"called Write() after read failure\n");
|
||||
ok(streamobj.seekcalls == 0,"called Seek() after read failure\n");
|
||||
|
||||
/* Read returns large object */
|
||||
InitDummyStream(&streamobj);
|
||||
streamobj.readreturnlarge = TRUE;
|
||||
hRet = pSHLWAPI_18(&streamobj, &list);
|
||||
ok(hRet == S_OK, "failed create from Read() with large item\n");
|
||||
ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
|
||||
ok(streamobj.readcalls == 1,"wrong call count\n");
|
||||
ok(streamobj.writecalls == 0,"called Write() after read failure\n");
|
||||
ok(streamobj.seekcalls == 2,"wrong Seek() call count (%d)\n", streamobj.seekcalls);
|
||||
|
||||
pSHLWAPI_19(list);
|
||||
}
|
||||
|
||||
static BOOL test_SHLWAPI_166(void)
|
||||
{
|
||||
_IDummyStream streamobj;
|
||||
BOOL bRet;
|
||||
|
||||
if (!pSHLWAPI_166)
|
||||
return FALSE;
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
bRet = pSHLWAPI_166(&streamobj);
|
||||
|
||||
if (bRet != TRUE)
|
||||
return FALSE; /* This version doesn't support stream ops on clists */
|
||||
|
||||
ok(streamobj.readcalls == 0, "called Read()\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 0, "called Seek()\n");
|
||||
ok(streamobj.statcalls == 1, "wrong call count\n");
|
||||
|
||||
streamobj.statcalls = 0;
|
||||
streamobj.pos.QuadPart = 50001;
|
||||
|
||||
bRet = pSHLWAPI_166(&streamobj);
|
||||
|
||||
ok(bRet == FALSE, "failed after seek adjusted\n");
|
||||
ok(streamobj.readcalls == 0, "called Read()\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 0, "called Seek()\n");
|
||||
ok(streamobj.statcalls == 1, "wrong call count\n");
|
||||
|
||||
/* Failure cases */
|
||||
InitDummyStream(&streamobj);
|
||||
streamobj.pos.QuadPart = 50001;
|
||||
streamobj.failstatcall = TRUE; /* 1: Stat() Bad, Read() OK */
|
||||
bRet = pSHLWAPI_166(&streamobj);
|
||||
ok(bRet == FALSE, "should be FALSE after read is OK\n");
|
||||
ok(streamobj.readcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.statcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.pos.QuadPart == 0, "Didn't seek to start\n");
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
streamobj.pos.QuadPart = 50001;
|
||||
streamobj.failstatcall = TRUE;
|
||||
streamobj.failreadcall = TRUE; /* 2: Stat() Bad, Read() Bad Also */
|
||||
bRet = pSHLWAPI_166(&streamobj);
|
||||
ok(bRet == TRUE, "Should be true after read fails\n");
|
||||
ok(streamobj.readcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 0, "Called Seek()\n");
|
||||
ok(streamobj.statcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.pos.QuadPart == 50001, "called Seek() after read failed\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_SHLWAPI_184(void)
|
||||
{
|
||||
_IDummyStream streamobj;
|
||||
char buff[256];
|
||||
HRESULT hRet;
|
||||
|
||||
if (!pSHLWAPI_184)
|
||||
return;
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
hRet = pSHLWAPI_184(&streamobj, buff, sizeof(buff));
|
||||
|
||||
ok(hRet == S_OK, "failed Read()\n");
|
||||
ok(streamobj.readcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 0, "called Seek()\n");
|
||||
}
|
||||
|
||||
static void test_SHLWAPI_212(void)
|
||||
{
|
||||
_IDummyStream streamobj;
|
||||
char buff[256];
|
||||
HRESULT hRet;
|
||||
|
||||
if (!pSHLWAPI_212)
|
||||
return;
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
hRet = pSHLWAPI_212(&streamobj, buff, sizeof(buff));
|
||||
|
||||
ok(hRet == S_OK, "failed Write()\n");
|
||||
ok(streamobj.readcalls == 0, "called Read()\n");
|
||||
ok(streamobj.writecalls == 1, "wrong call count\n");
|
||||
ok(streamobj.seekcalls == 0, "called Seek()\n");
|
||||
}
|
||||
|
||||
static void test_SHLWAPI_213(void)
|
||||
{
|
||||
_IDummyStream streamobj;
|
||||
ULARGE_INTEGER ul;
|
||||
LARGE_INTEGER ll;
|
||||
HRESULT hRet;
|
||||
|
||||
if (!pSHLWAPI_213 || !pSHLWAPI_214)
|
||||
return;
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
ll.QuadPart = 5000l;
|
||||
Seek(&streamobj, ll, 0, NULL); /* Seek to 5000l */
|
||||
|
||||
streamobj.seekcalls = 0;
|
||||
pSHLWAPI_213(&streamobj); /* Should rewind */
|
||||
ok(streamobj.statcalls == 0, "called Stat()\n");
|
||||
ok(streamobj.readcalls == 0, "called Read()\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 1, "wrong call count\n");
|
||||
|
||||
ul.QuadPart = 50001;
|
||||
hRet = pSHLWAPI_214(&streamobj, &ul);
|
||||
ok(hRet == S_OK, "failed Stat()\n");
|
||||
ok(ul.QuadPart == 0, "213 didn't rewind stream\n");
|
||||
}
|
||||
|
||||
static void test_SHLWAPI_214(void)
|
||||
{
|
||||
_IDummyStream streamobj;
|
||||
ULARGE_INTEGER ul;
|
||||
LARGE_INTEGER ll;
|
||||
HRESULT hRet;
|
||||
|
||||
if (!pSHLWAPI_214)
|
||||
return;
|
||||
|
||||
InitDummyStream(&streamobj);
|
||||
ll.QuadPart = 5000l;
|
||||
Seek(&streamobj, ll, 0, NULL);
|
||||
ul.QuadPart = 0;
|
||||
streamobj.seekcalls = 0;
|
||||
hRet = pSHLWAPI_214(&streamobj, &ul);
|
||||
|
||||
ok(hRet == S_OK, "failed Stat()\n");
|
||||
ok(streamobj.statcalls == 1, "wrong call count\n");
|
||||
ok(streamobj.readcalls == 0, "called Read()\n");
|
||||
ok(streamobj.writecalls == 0, "called Write()\n");
|
||||
ok(streamobj.seekcalls == 0, "called Seek()\n");
|
||||
ok(ul.QuadPart == 5000l, "Stat gave wrong size\n");
|
||||
}
|
||||
|
||||
START_TEST(clist)
|
||||
{
|
||||
InitFunctionPtrs();
|
||||
|
||||
test_CList();
|
||||
|
||||
/* Test streaming if this version supports it */
|
||||
if (test_SHLWAPI_166())
|
||||
{
|
||||
test_SHLWAPI_184();
|
||||
test_SHLWAPI_212();
|
||||
test_SHLWAPI_213();
|
||||
test_SHLWAPI_214();
|
||||
}
|
||||
|
||||
if (SHLWAPI_hshlwapi)
|
||||
FreeLibrary(SHLWAPI_hshlwapi);
|
||||
}
|
171
reactos/regtests/winetests/shlwapi/clsid.c
Executable file
171
reactos/regtests/winetests/shlwapi/clsid.c
Executable file
|
@ -0,0 +1,171 @@
|
|||
/* Unit test suite for SHLWAPI Class ID functions
|
||||
*
|
||||
* Copyright 2003 Jon Griffiths
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define INITGUID
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
#include "winuser.h"
|
||||
#include "shlguid.h"
|
||||
#include "wine/shobjidl.h"
|
||||
|
||||
/* Function ptrs for ordinal calls */
|
||||
static HMODULE hShlwapi = 0;
|
||||
static BOOL (WINAPI *pSHLWAPI_269)(LPCSTR, CLSID *) = 0;
|
||||
static DWORD (WINAPI *pSHLWAPI_23)(REFGUID, LPSTR, INT) = 0;
|
||||
|
||||
/* GUIDs to test */
|
||||
const GUID * TEST_guids[] = {
|
||||
&CLSID_ShellDesktop,
|
||||
&CLSID_ShellLink,
|
||||
&CATID_BrowsableShellExt,
|
||||
&CATID_BrowseInPlace,
|
||||
&CATID_DeskBand,
|
||||
&CATID_InfoBand,
|
||||
&CATID_CommBand,
|
||||
&FMTID_Intshcut,
|
||||
&FMTID_InternetSite,
|
||||
&CGID_Explorer,
|
||||
&CGID_ShellDocView,
|
||||
&CGID_ShellServiceObject,
|
||||
&CGID_ExplorerBarDoc,
|
||||
&IID_INewShortcutHookA,
|
||||
&IID_IShellIcon,
|
||||
&IID_IShellFolder,
|
||||
&IID_IShellExtInit,
|
||||
&IID_IShellPropSheetExt,
|
||||
&IID_IPersistFolder,
|
||||
&IID_IExtractIconA,
|
||||
&IID_IShellDetails,
|
||||
&IID_IDelayedRelease,
|
||||
&IID_IShellLinkA,
|
||||
&IID_IShellCopyHookA,
|
||||
&IID_IFileViewerA,
|
||||
&IID_ICommDlgBrowser,
|
||||
&IID_IEnumIDList,
|
||||
&IID_IFileViewerSite,
|
||||
&IID_IContextMenu2,
|
||||
&IID_IShellExecuteHookA,
|
||||
&IID_IPropSheetPage,
|
||||
&IID_INewShortcutHookW,
|
||||
&IID_IFileViewerW,
|
||||
&IID_IShellLinkW,
|
||||
&IID_IExtractIconW,
|
||||
&IID_IShellExecuteHookW,
|
||||
&IID_IShellCopyHookW,
|
||||
&IID_IRemoteComputer,
|
||||
&IID_IQueryInfo,
|
||||
&IID_IDockingWindow,
|
||||
&IID_IDockingWindowSite,
|
||||
&CLSID_NetworkPlaces,
|
||||
&CLSID_NetworkDomain,
|
||||
&CLSID_NetworkServer,
|
||||
&CLSID_NetworkShare,
|
||||
&CLSID_MyComputer,
|
||||
&CLSID_Internet,
|
||||
&CLSID_ShellFSFolder,
|
||||
&CLSID_RecycleBin,
|
||||
&CLSID_ControlPanel,
|
||||
&CLSID_Printers,
|
||||
&CLSID_MyDocuments,
|
||||
NULL
|
||||
};
|
||||
|
||||
DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B,
|
||||
0x0C, 0x0D, 0x0E, 0x0F, 0x0A);
|
||||
|
||||
static void test_ClassIDs(void)
|
||||
{
|
||||
const GUID **guids = TEST_guids;
|
||||
char szBuff[256];
|
||||
GUID guid;
|
||||
DWORD dwLen;
|
||||
BOOL bRet;
|
||||
int i = 0;
|
||||
|
||||
if (!pSHLWAPI_269 || !pSHLWAPI_23)
|
||||
return;
|
||||
|
||||
while (*guids)
|
||||
{
|
||||
dwLen = pSHLWAPI_23(*guids, szBuff, 256);
|
||||
ok(dwLen == 39, "wrong size for id %d\n", i);
|
||||
|
||||
bRet = pSHLWAPI_269(szBuff, &guid);
|
||||
ok(bRet != FALSE, "created invalid string '%s'\n", szBuff);
|
||||
|
||||
if (bRet)
|
||||
ok(IsEqualGUID(*guids, &guid), "GUID created wrong %d\n", i);
|
||||
|
||||
guids++;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Test endianess */
|
||||
dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 256);
|
||||
ok(dwLen == 39, "wrong size for IID_Endianess\n");
|
||||
|
||||
ok(!strcmp(szBuff, "{01020304-0506-0708-090A-0B0C0D0E0F0A}"),
|
||||
"Endianess Broken, got '%s'\n", szBuff);
|
||||
|
||||
/* test lengths */
|
||||
szBuff[0] = ':';
|
||||
dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 0);
|
||||
ok(dwLen == 0, "accepted bad length\n");
|
||||
ok(szBuff[0] == ':', "wrote to buffer with no length\n");
|
||||
|
||||
szBuff[0] = ':';
|
||||
dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 38);
|
||||
ok(dwLen == 0, "accepted bad length\n");
|
||||
ok(szBuff[0] == ':', "wrote to buffer with no length\n");
|
||||
|
||||
szBuff[0] = ':';
|
||||
dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 39);
|
||||
ok(dwLen == 39, "rejected ok length\n");
|
||||
ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n");
|
||||
|
||||
/* Test string */
|
||||
strcpy(szBuff, "{xxx-");
|
||||
bRet = pSHLWAPI_269(szBuff, &guid);
|
||||
ok(bRet == FALSE, "accepted invalid string\n");
|
||||
|
||||
dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 39);
|
||||
ok(dwLen == 39, "rejected ok length\n");
|
||||
ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n");
|
||||
}
|
||||
|
||||
|
||||
START_TEST(clsid)
|
||||
{
|
||||
hShlwapi = LoadLibraryA("shlwapi.dll");
|
||||
ok(hShlwapi != 0, "LoadLibraryA failed\n");
|
||||
if (hShlwapi)
|
||||
{
|
||||
pSHLWAPI_269 = (void*)GetProcAddress(hShlwapi, (LPSTR)269);
|
||||
pSHLWAPI_23 = (void*)GetProcAddress(hShlwapi, (LPSTR)23);
|
||||
}
|
||||
|
||||
test_ClassIDs();
|
||||
|
||||
if (hShlwapi)
|
||||
FreeLibrary(hShlwapi);
|
||||
}
|
186
reactos/regtests/winetests/shlwapi/generated.c
Executable file
186
reactos/regtests/winetests/shlwapi/generated.c
Executable file
|
@ -0,0 +1,186 @@
|
|||
/* File generated automatically from tools/winapi/test.dat; do not edit! */
|
||||
/* This file can be copied, modified and distributed without restriction. */
|
||||
|
||||
/*
|
||||
* Unit tests for data structure packing
|
||||
*/
|
||||
|
||||
#define WINVER 0x0501
|
||||
#define _WIN32_IE 0x0501
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
#define WINE_NOWINSOCK
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wtypes.h"
|
||||
#include "winreg.h"
|
||||
#include "shlwapi.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Compability macros
|
||||
*/
|
||||
|
||||
#define DWORD_PTR UINT_PTR
|
||||
#define LONG_PTR INT_PTR
|
||||
#define ULONG_PTR UINT_PTR
|
||||
|
||||
/***********************************************************************
|
||||
* Windows API extension
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus)
|
||||
# define FIELD_ALIGNMENT(type, field) __alignof(((type*)0)->field)
|
||||
#elif defined(__GNUC__)
|
||||
# define FIELD_ALIGNMENT(type, field) __alignof__(((type*)0)->field)
|
||||
#else
|
||||
/* FIXME: Not sure if is possible to do without compiler extension */
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus)
|
||||
# define _TYPE_ALIGNMENT(type) __alignof(type)
|
||||
#elif defined(__GNUC__)
|
||||
# define _TYPE_ALIGNMENT(type) __alignof__(type)
|
||||
#else
|
||||
/*
|
||||
* FIXME: Not sure if is possible to do without compiler extension
|
||||
* (if type is not just a name that is, if so the normal)
|
||||
* TYPE_ALIGNMENT can be used)
|
||||
*/
|
||||
#endif
|
||||
|
||||
#if defined(TYPE_ALIGNMENT) && defined(_MSC_VER) && _MSC_VER >= 800 && !defined(__cplusplus)
|
||||
#pragma warning(disable:4116)
|
||||
#endif
|
||||
|
||||
#if !defined(TYPE_ALIGNMENT) && defined(_TYPE_ALIGNMENT)
|
||||
# define TYPE_ALIGNMENT _TYPE_ALIGNMENT
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Test helper macros
|
||||
*/
|
||||
|
||||
#ifdef FIELD_ALIGNMENT
|
||||
# define TEST_FIELD_ALIGNMENT(type, field, align) \
|
||||
ok(FIELD_ALIGNMENT(type, field) == align, \
|
||||
"FIELD_ALIGNMENT(" #type ", " #field ") == %d (expected " #align ")\n", \
|
||||
(int)FIELD_ALIGNMENT(type, field))
|
||||
#else
|
||||
# define TEST_FIELD_ALIGNMENT(type, field, align) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define TEST_FIELD_OFFSET(type, field, offset) \
|
||||
ok(FIELD_OFFSET(type, field) == offset, \
|
||||
"FIELD_OFFSET(" #type ", " #field ") == %ld (expected " #offset ")\n", \
|
||||
(long int)FIELD_OFFSET(type, field))
|
||||
|
||||
#ifdef _TYPE_ALIGNMENT
|
||||
#define TEST__TYPE_ALIGNMENT(type, align) \
|
||||
ok(_TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)_TYPE_ALIGNMENT(type))
|
||||
#else
|
||||
# define TEST__TYPE_ALIGNMENT(type, align) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef TYPE_ALIGNMENT
|
||||
#define TEST_TYPE_ALIGNMENT(type, align) \
|
||||
ok(TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)TYPE_ALIGNMENT(type))
|
||||
#else
|
||||
# define TEST_TYPE_ALIGNMENT(type, align) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define TEST_TYPE_SIZE(type, size) \
|
||||
ok(sizeof(type) == size, "sizeof(" #type ") == %d (expected " #size ")\n", ((int) sizeof(type)))
|
||||
|
||||
/***********************************************************************
|
||||
* Test macros
|
||||
*/
|
||||
|
||||
#define TEST_FIELD(type, field_type, field_name, field_offset, field_size, field_align) \
|
||||
TEST_TYPE_SIZE(field_type, field_size); \
|
||||
TEST_FIELD_ALIGNMENT(type, field_name, field_align); \
|
||||
TEST_FIELD_OFFSET(type, field_name, field_offset); \
|
||||
|
||||
#define TEST_TYPE(type, size, align) \
|
||||
TEST_TYPE_ALIGNMENT(type, align); \
|
||||
TEST_TYPE_SIZE(type, size)
|
||||
|
||||
#define TEST_TYPE_POINTER(type, size, align) \
|
||||
TEST__TYPE_ALIGNMENT(*(type)0, align); \
|
||||
TEST_TYPE_SIZE(*(type)0, size)
|
||||
|
||||
#define TEST_TYPE_SIGNED(type) \
|
||||
ok((type) -1 < 0, "(" #type ") -1 < 0\n");
|
||||
|
||||
#define TEST_TYPE_UNSIGNED(type) \
|
||||
ok((type) -1 > 0, "(" #type ") -1 > 0\n");
|
||||
|
||||
static void test_pack_ASSOCF(void)
|
||||
{
|
||||
/* ASSOCF */
|
||||
TEST_TYPE(ASSOCF, 4, 4);
|
||||
TEST_TYPE_UNSIGNED(ASSOCF);
|
||||
}
|
||||
|
||||
static void test_pack_DLLGETVERSIONPROC(void)
|
||||
{
|
||||
/* DLLGETVERSIONPROC */
|
||||
TEST_TYPE(DLLGETVERSIONPROC, 4, 4);
|
||||
}
|
||||
|
||||
static void test_pack_DLLVERSIONINFO(void)
|
||||
{
|
||||
/* DLLVERSIONINFO (pack 8) */
|
||||
TEST_TYPE(DLLVERSIONINFO, 20, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO, DWORD, cbSize, 0, 4, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO, DWORD, dwMajorVersion, 4, 4, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO, DWORD, dwMinorVersion, 8, 4, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO, DWORD, dwBuildNumber, 12, 4, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO, DWORD, dwPlatformID, 16, 4, 4);
|
||||
}
|
||||
|
||||
static void test_pack_DLLVERSIONINFO2(void)
|
||||
{
|
||||
/* DLLVERSIONINFO2 (pack 8) */
|
||||
TEST_TYPE(DLLVERSIONINFO2, 32, 8);
|
||||
TEST_FIELD(DLLVERSIONINFO2, DLLVERSIONINFO, info1, 0, 20, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO2, DWORD, dwFlags, 20, 4, 4);
|
||||
TEST_FIELD(DLLVERSIONINFO2, ULONGLONG, ullVersion, 24, 8, 8);
|
||||
}
|
||||
|
||||
static void test_pack_HUSKEY(void)
|
||||
{
|
||||
/* HUSKEY */
|
||||
TEST_TYPE(HUSKEY, 4, 4);
|
||||
}
|
||||
|
||||
static void test_pack_IQueryAssociations(void)
|
||||
{
|
||||
/* IQueryAssociations */
|
||||
}
|
||||
|
||||
static void test_pack_PHUSKEY(void)
|
||||
{
|
||||
/* PHUSKEY */
|
||||
TEST_TYPE(PHUSKEY, 4, 4);
|
||||
TEST_TYPE_POINTER(PHUSKEY, 4, 4);
|
||||
}
|
||||
|
||||
static void test_pack(void)
|
||||
{
|
||||
test_pack_ASSOCF();
|
||||
test_pack_DLLGETVERSIONPROC();
|
||||
test_pack_DLLVERSIONINFO();
|
||||
test_pack_DLLVERSIONINFO2();
|
||||
test_pack_HUSKEY();
|
||||
test_pack_IQueryAssociations();
|
||||
test_pack_PHUSKEY();
|
||||
}
|
||||
|
||||
START_TEST(generated)
|
||||
{
|
||||
test_pack();
|
||||
}
|
248
reactos/regtests/winetests/shlwapi/ordinal.c
Executable file
248
reactos/regtests/winetests/shlwapi/ordinal.c
Executable file
|
@ -0,0 +1,248 @@
|
|||
/* Unit test suite for SHLWAPI ordinal functions
|
||||
*
|
||||
* Copyright 2004 Jon Griffiths
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winuser.h"
|
||||
|
||||
/* Function ptrs for ordinal calls */
|
||||
static HMODULE hShlwapi;
|
||||
static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
|
||||
static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
|
||||
|
||||
static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
|
||||
static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
|
||||
static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
|
||||
static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
|
||||
|
||||
static void test_GetAcceptLanguagesA(void)
|
||||
{ HRESULT retval;
|
||||
DWORD buffersize, buffersize2, exactsize;
|
||||
char buffer[100];
|
||||
|
||||
if (!pGetAcceptLanguagesA)
|
||||
return;
|
||||
|
||||
buffersize = sizeof(buffer);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( buffer, &buffersize);
|
||||
trace("GetAcceptLanguagesA: retval %08lx, size %08lx, buffer (%s),"
|
||||
" last error %ld\n", retval, buffersize, buffer, GetLastError());
|
||||
if(retval != S_OK) {
|
||||
trace("GetAcceptLanguagesA: skipping tests\n");
|
||||
return;
|
||||
}
|
||||
ok( (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()) ||
|
||||
(ERROR_CLASS_DOES_NOT_EXIST == GetLastError()) ||
|
||||
(ERROR_PROC_NOT_FOUND == GetLastError()) ||
|
||||
(ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) ||
|
||||
(ERROR_SUCCESS == GetLastError()), "last error set to %ld\n", GetLastError());
|
||||
exactsize = strlen(buffer);
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( NULL, NULL);
|
||||
ok(retval == E_FAIL,
|
||||
"function result wrong: got %08lx; expected E_FAIL\n", retval);
|
||||
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
|
||||
|
||||
buffersize = sizeof(buffer);
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( NULL, &buffersize);
|
||||
ok(retval == E_FAIL,
|
||||
"function result wrong: got %08lx; expected E_FAIL\n", retval);
|
||||
ok(buffersize == sizeof(buffer),
|
||||
"buffersize was changed (2nd parameter; not on Win2k)\n");
|
||||
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( buffer, NULL);
|
||||
ok(retval == E_FAIL,
|
||||
"function result wrong: got %08lx; expected E_FAIL\n", retval);
|
||||
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
|
||||
|
||||
buffersize = 0;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( buffer, &buffersize);
|
||||
ok(retval == E_FAIL,
|
||||
"function result wrong: got %08lx; expected E_FAIL\n", retval);
|
||||
ok(buffersize == 0,
|
||||
"buffersize wrong(changed) got %08lx; expected 0 (2nd parameter; not on Win2k)\n", buffersize);
|
||||
ok(ERROR_SUCCESS == GetLastError(), "last error set to %ld\n", GetLastError());
|
||||
|
||||
buffersize = buffersize2 = 1;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( buffer, &buffersize);
|
||||
switch(retval) {
|
||||
case 0L:
|
||||
if(buffersize == exactsize) {
|
||||
ok( (ERROR_SUCCESS == GetLastError()) || (ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) ||
|
||||
(ERROR_PROC_NOT_FOUND == GetLastError()) || (ERROR_NO_IMPERSONATION_TOKEN == GetLastError()),
|
||||
"last error wrong: got %08lx; expected ERROR_SUCCESS(NT4)/ERROR_CALL_NOT_IMPLEMENTED(98/ME)/"
|
||||
"ERROR_PROC_NOT_FOUND(NT4)/ERROR_NO_IMPERSONATION_TOKEN(XP)\n", GetLastError());
|
||||
ok(exactsize == strlen(buffer),
|
||||
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), exactsize);
|
||||
} else if((buffersize +1) == buffersize2) {
|
||||
ok(ERROR_SUCCESS == GetLastError(),
|
||||
"last error wrong: got %08lx; expected ERROR_SUCCESS\n", GetLastError());
|
||||
ok(buffersize == strlen(buffer),
|
||||
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize);
|
||||
} else
|
||||
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
|
||||
retval, buffersize, buffer, GetLastError());
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
ok(buffersize == 0,
|
||||
"buffersize wrong: got %08lx, expected 0 (2nd parameter;Win2k)\n", buffersize);
|
||||
ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
|
||||
"last error wrong: got %08lx; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
|
||||
ok(buffersize2 == strlen(buffer),
|
||||
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize2);
|
||||
break;
|
||||
default:
|
||||
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
|
||||
retval, buffersize, buffer, GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
buffersize = buffersize2 = exactsize;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
retval = pGetAcceptLanguagesA( buffer, &buffersize);
|
||||
switch(retval) {
|
||||
case 0L:
|
||||
ok(ERROR_SUCCESS == GetLastError(),
|
||||
"last error wrong: got %08lx; expected ERROR_SUCCESS\n", GetLastError());
|
||||
if((buffersize == exactsize) /* XP */ ||
|
||||
((buffersize +1)== exactsize) /* 98 */)
|
||||
ok(buffersize == strlen(buffer),
|
||||
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize);
|
||||
else
|
||||
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
|
||||
retval, buffersize, buffer, GetLastError());
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
ok(buffersize == 0,
|
||||
"buffersize wrong: got %08lx, expected 0 (2nd parameter;Win2k)\n", buffersize);
|
||||
ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
|
||||
"last error wrong: got %08lx; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
|
||||
ok(buffersize2 == strlen(buffer),
|
||||
"buffer content (length) wrong: got %08x, expected %08lx \n", strlen(buffer), buffersize2);
|
||||
break;
|
||||
default:
|
||||
ok( 0, "retval %08lx, size %08lx, buffer (%s), last error %ld\n",
|
||||
retval, buffersize, buffer, GetLastError());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_SHSearchMapInt(void)
|
||||
{
|
||||
int keys[8], values[8];
|
||||
int i = 0;
|
||||
|
||||
if (!pSHSearchMapInt)
|
||||
return;
|
||||
|
||||
memset(keys, 0, sizeof(keys));
|
||||
memset(values, 0, sizeof(values));
|
||||
keys[0] = 99; values[0] = 101;
|
||||
|
||||
/* NULL key/value lists crash native, so skip testing them */
|
||||
|
||||
/* 1 element */
|
||||
i = pSHSearchMapInt(keys, values, 1, keys[0]);
|
||||
ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
|
||||
|
||||
/* Key doesn't exist */
|
||||
i = pSHSearchMapInt(keys, values, 1, 100);
|
||||
ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
|
||||
|
||||
/* Len = 0 => not found */
|
||||
i = pSHSearchMapInt(keys, values, 0, keys[0]);
|
||||
ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
|
||||
|
||||
/* 2 elements, len = 1 */
|
||||
keys[1] = 98; values[1] = 102;
|
||||
i = pSHSearchMapInt(keys, values, 1, keys[1]);
|
||||
ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
|
||||
|
||||
/* 2 elements, len = 2 */
|
||||
i = pSHSearchMapInt(keys, values, 2, keys[1]);
|
||||
ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
|
||||
|
||||
/* Searches forward */
|
||||
keys[2] = 99; values[2] = 103;
|
||||
i = pSHSearchMapInt(keys, values, 3, keys[0]);
|
||||
ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
|
||||
}
|
||||
|
||||
static void test_alloc_shared(void)
|
||||
{
|
||||
DWORD procid;
|
||||
HANDLE hmem;
|
||||
int val;
|
||||
int* p;
|
||||
BOOL ret;
|
||||
|
||||
procid=GetCurrentProcessId();
|
||||
hmem=pSHAllocShared(NULL,10,procid);
|
||||
ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %ld\n", GetLastError());
|
||||
ret = pSHFreeShared(hmem, procid);
|
||||
ok( ret, "SHFreeShared failed: %ld\n", GetLastError());
|
||||
|
||||
val=0x12345678;
|
||||
hmem=pSHAllocShared(&val,4,procid);
|
||||
ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %ld\n", GetLastError());
|
||||
|
||||
p=(int*)pSHLockShared(hmem,procid);
|
||||
ok(p!=NULL,"SHLockShared failed: %ld\n", GetLastError());
|
||||
if (p!=NULL)
|
||||
ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
|
||||
ret = pSHUnlockShared(p);
|
||||
ok( ret, "SHUnlockShared failed: %ld\n", GetLastError());
|
||||
|
||||
ret = pSHFreeShared(hmem, procid);
|
||||
ok( ret, "SHFreeShared failed: %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
START_TEST(ordinal)
|
||||
{
|
||||
hShlwapi = LoadLibraryA("shlwapi.dll");
|
||||
ok(hShlwapi != 0, "LoadLibraryA failed\n");
|
||||
if (!hShlwapi)
|
||||
return;
|
||||
|
||||
pGetAcceptLanguagesA = (void*)GetProcAddress(hShlwapi, (LPSTR)14);
|
||||
pSHSearchMapInt = (void*)GetProcAddress(hShlwapi, (LPSTR)198);
|
||||
pSHAllocShared=(void*)GetProcAddress(hShlwapi,(char*)7);
|
||||
pSHLockShared=(void*)GetProcAddress(hShlwapi,(char*)8);
|
||||
pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
|
||||
pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
|
||||
|
||||
test_GetAcceptLanguagesA();
|
||||
test_SHSearchMapInt();
|
||||
test_alloc_shared();
|
||||
FreeLibrary(hShlwapi);
|
||||
}
|
833
reactos/regtests/winetests/shlwapi/path.c
Executable file
833
reactos/regtests/winetests/shlwapi/path.c
Executable file
|
@ -0,0 +1,833 @@
|
|||
/* Unit test suite for Path functions
|
||||
*
|
||||
* Copyright 2002 Matthew Mastracci
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "winreg.h"
|
||||
#include "shlwapi.h"
|
||||
#include "wininet.h"
|
||||
|
||||
static HMODULE hShlwapi;
|
||||
static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
|
||||
static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
|
||||
|
||||
const char* TEST_URL_1 = "http://www.winehq.org/tests?date=10/10/1923";
|
||||
const char* TEST_URL_2 = "http://localhost:8080/tests%2e.html?date=Mon%2010/10/1923";
|
||||
const char* TEST_URL_3 = "http://foo:bar@localhost:21/internal.php?query=x&return=y";
|
||||
|
||||
typedef struct _TEST_URL_CANONICALIZE {
|
||||
const char *url;
|
||||
DWORD flags;
|
||||
HRESULT expectret;
|
||||
const char *expecturl;
|
||||
} TEST_URL_CANONICALIZE;
|
||||
|
||||
const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
|
||||
/*FIXME {"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/"},*/
|
||||
{"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests"},
|
||||
{"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
|
||||
{"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
|
||||
{"http://www.winehq.org/tests\r", 0, S_OK, "http://www.winehq.org/tests"},
|
||||
{"http://www.winehq.org/tests\r", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests"},
|
||||
{"http://www.winehq.org/tests/../tests/", 0, S_OK, "http://www.winehq.org/tests/"},
|
||||
{"http://www.winehq.org/tests/../tests/..", 0, S_OK, "http://www.winehq.org/"},
|
||||
{"http://www.winehq.org/tests/../tests/../", 0, S_OK, "http://www.winehq.org/"},
|
||||
{"http://www.winehq.org/tests/..", 0, S_OK, "http://www.winehq.org/"},
|
||||
{"http://www.winehq.org/tests/../", 0, S_OK, "http://www.winehq.org/"},
|
||||
{"http://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
|
||||
{"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
|
||||
{"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||
{"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
|
||||
{"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
|
||||
{"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar"},
|
||||
{"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
|
||||
{"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
|
||||
};
|
||||
|
||||
typedef struct _TEST_URL_ESCAPE {
|
||||
const char *url;
|
||||
DWORD flags;
|
||||
DWORD expectescaped;
|
||||
HRESULT expectret;
|
||||
const char *expecturl;
|
||||
} TEST_URL_ESCAPE;
|
||||
|
||||
const TEST_URL_ESCAPE TEST_ESCAPE[] = {
|
||||
{"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
|
||||
{"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
|
||||
{"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
|
||||
{"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
|
||||
{"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
|
||||
{"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
|
||||
{"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
|
||||
|
||||
{"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
|
||||
{"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
|
||||
{"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
|
||||
{"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
|
||||
{"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
|
||||
{"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
|
||||
{"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
|
||||
{"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
|
||||
{"file:/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
|
||||
{"file:foo/bar\\baz", 0, 0, S_OK, "file:foo/bar/baz"},
|
||||
{"file:\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
|
||||
{"file:\\\\foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
|
||||
{"file:\\\\\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
|
||||
{"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
|
||||
{"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
|
||||
{"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
|
||||
{"file:///f o^&`{}|][\"<>\\%o/b#a r\\baz", 0, 0, S_OK, "file:///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"},
|
||||
{"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
|
||||
{"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
|
||||
|
||||
{"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
|
||||
{"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
|
||||
{"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"},
|
||||
{"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"},
|
||||
{"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
|
||||
{"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
|
||||
{"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
|
||||
|
||||
{"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"},
|
||||
{"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"},
|
||||
{"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
|
||||
{"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
|
||||
{"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
|
||||
{"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
|
||||
{"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
|
||||
{"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
|
||||
{"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
|
||||
{"http:\\foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
|
||||
{"http:\\\\foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
|
||||
{"http:\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
|
||||
{"http:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
|
||||
{"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
|
||||
{"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
|
||||
{"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
|
||||
|
||||
{"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"},
|
||||
{"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
|
||||
{"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
|
||||
|
||||
{"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
|
||||
{"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
|
||||
{"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"},
|
||||
{"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"},
|
||||
{"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"},
|
||||
{"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
|
||||
{"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
|
||||
{"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
|
||||
{"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
|
||||
|
||||
{"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
|
||||
{"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
|
||||
{"mailto:fo/o@b\\%a?\\r.b#\\az", URL_ESCAPE_PERCENT, 0, S_OK, "mailto:fo%2Fo@b%5C%25a%3F%5Cr.b%23%5Caz"},
|
||||
|
||||
{"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
|
||||
{"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
|
||||
{"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
|
||||
{"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
|
||||
{"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
|
||||
{"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
|
||||
{"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}
|
||||
};
|
||||
|
||||
typedef struct _TEST_URL_COMBINE {
|
||||
const char *url1;
|
||||
const char *url2;
|
||||
DWORD flags;
|
||||
HRESULT expectret;
|
||||
const char *expecturl;
|
||||
} TEST_URL_COMBINE;
|
||||
|
||||
const TEST_URL_COMBINE TEST_COMBINE[] = {
|
||||
{"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
|
||||
/*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
|
||||
{"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
|
||||
{"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
|
||||
{"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
|
||||
{"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
|
||||
{"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
|
||||
{"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
|
||||
{"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
|
||||
{"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
|
||||
{"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *path;
|
||||
const char *url;
|
||||
DWORD ret;
|
||||
} TEST_URLFROMPATH [] = {
|
||||
{"foo", "file:foo", S_OK},
|
||||
{"foo\\bar", "file:foo/bar", S_OK},
|
||||
{"\\foo\\bar", "file:///foo/bar", S_OK},
|
||||
{"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
|
||||
{"c:foo\\bar", "file:///c:foo/bar", S_OK},
|
||||
{"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
|
||||
{"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
|
||||
#if 0
|
||||
/* The following test fails on native shlwapi as distributed with Win95/98.
|
||||
* Wine matches the behaviour of later versions.
|
||||
*/
|
||||
{"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *url;
|
||||
const char *path;
|
||||
DWORD ret;
|
||||
} TEST_PATHFROMURL[] = {
|
||||
{"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
|
||||
{"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
|
||||
{"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
|
||||
{"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
|
||||
{"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
|
||||
{"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
|
||||
{"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
|
||||
{"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
|
||||
{"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
|
||||
{"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
|
||||
{"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
|
||||
{"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
|
||||
{"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
|
||||
{"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
|
||||
{"file:/foo/bar", "\\foo\\bar", S_OK},
|
||||
{"file:/foo/bar/", "\\foo\\bar\\", S_OK},
|
||||
{"file:foo/bar", "foo\\bar", S_OK},
|
||||
{"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
|
||||
{"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
|
||||
{"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
|
||||
{"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
|
||||
/* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
|
||||
|
||||
{"c:\\foo\\bar", NULL, E_INVALIDARG},
|
||||
{"foo/bar", NULL, E_INVALIDARG},
|
||||
{"http://foo/bar", NULL, E_INVALIDARG},
|
||||
|
||||
};
|
||||
|
||||
struct {
|
||||
char url[30];
|
||||
const char *expect;
|
||||
} TEST_URL_UNESCAPE[] = {
|
||||
{"file://foo/bar", "file://foo/bar"},
|
||||
{"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
|
||||
};
|
||||
|
||||
|
||||
struct {
|
||||
const char *path;
|
||||
BOOL expect;
|
||||
} TEST_PATH_IS_URL[] = {
|
||||
{"http://foo/bar", TRUE},
|
||||
{"c:\\foo\\bar", FALSE},
|
||||
{"foo://foo/bar", TRUE},
|
||||
{"foo\\bar", FALSE},
|
||||
{"foo.bar", FALSE},
|
||||
{"bogusscheme:", TRUE},
|
||||
{"http:partial", TRUE}
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *url;
|
||||
BOOL expectOpaque;
|
||||
BOOL expectFile;
|
||||
} TEST_URLIS_ATTRIBS[] = {
|
||||
{ "ftp:", FALSE, FALSE },
|
||||
{ "http:", FALSE, FALSE },
|
||||
{ "gopher:", FALSE, FALSE },
|
||||
{ "mailto:", TRUE, FALSE },
|
||||
{ "news:", FALSE, FALSE },
|
||||
{ "nntp:", FALSE, FALSE },
|
||||
{ "telnet:", FALSE, FALSE },
|
||||
{ "wais:", FALSE, FALSE },
|
||||
{ "file:", FALSE, TRUE },
|
||||
{ "mk:", FALSE, FALSE },
|
||||
{ "https:", FALSE, FALSE },
|
||||
{ "shell:", TRUE, FALSE },
|
||||
{ "https:", FALSE, FALSE },
|
||||
{ "snews:", FALSE, FALSE },
|
||||
{ "local:", FALSE, FALSE },
|
||||
{ "javascript:", TRUE, FALSE },
|
||||
{ "vbscript:", TRUE, FALSE },
|
||||
{ "about:", TRUE, FALSE },
|
||||
{ "res:", FALSE, FALSE },
|
||||
{ "bogusscheme:", FALSE, FALSE },
|
||||
{ "file:\\\\e:\\b\\c", FALSE, TRUE },
|
||||
{ "file://e:/b/c", FALSE, TRUE },
|
||||
{ "http:partial", FALSE, FALSE },
|
||||
{ "mailto://www.winehq.org/test.html", TRUE, FALSE },
|
||||
{ "file:partial", FALSE, TRUE }
|
||||
};
|
||||
|
||||
|
||||
static LPWSTR GetWideString(const char* szString)
|
||||
{
|
||||
LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
|
||||
|
||||
MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
|
||||
|
||||
return wszString;
|
||||
}
|
||||
|
||||
static void FreeWideString(LPWSTR wszString)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, wszString);
|
||||
}
|
||||
|
||||
static void hash_url(const char* szUrl)
|
||||
{
|
||||
LPCSTR szTestUrl = szUrl;
|
||||
LPWSTR wszTestUrl = GetWideString(szTestUrl);
|
||||
|
||||
DWORD cbSize = sizeof(DWORD);
|
||||
DWORD dwHash1, dwHash2;
|
||||
ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
|
||||
ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
|
||||
|
||||
FreeWideString(wszTestUrl);
|
||||
|
||||
ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
|
||||
}
|
||||
|
||||
static void test_UrlHash(void)
|
||||
{
|
||||
hash_url(TEST_URL_1);
|
||||
hash_url(TEST_URL_2);
|
||||
hash_url(TEST_URL_3);
|
||||
}
|
||||
|
||||
static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
|
||||
{
|
||||
CHAR szPart[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
|
||||
LPWSTR wszUrl = GetWideString(szUrl);
|
||||
LPWSTR wszConvertedPart;
|
||||
|
||||
DWORD dwSize;
|
||||
|
||||
dwSize = INTERNET_MAX_URL_LENGTH;
|
||||
ok( UrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartA for \"%s\" part 0x%08lx didn't return S_OK but \"%s\"\n", szUrl, dwPart, szPart);
|
||||
dwSize = INTERNET_MAX_URL_LENGTH;
|
||||
ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
|
||||
|
||||
wszConvertedPart = GetWideString(szPart);
|
||||
|
||||
ok(strcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
|
||||
|
||||
FreeWideString(wszUrl);
|
||||
FreeWideString(wszConvertedPart);
|
||||
|
||||
/* Note that v6.0 and later don't return '?' with the query */
|
||||
ok(strcmp(szPart,szExpected)==0 ||
|
||||
(*szExpected=='?' && !strcmp(szPart,szExpected+1)),
|
||||
"Expected %s, but got %s\n", szExpected, szPart);
|
||||
}
|
||||
|
||||
static void test_UrlGetPart(void)
|
||||
{
|
||||
test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
|
||||
test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
|
||||
test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
|
||||
test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
|
||||
test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
|
||||
test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
|
||||
}
|
||||
|
||||
static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
|
||||
{
|
||||
CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
DWORD dwEscaped;
|
||||
WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR *urlW, *expected_urlW;
|
||||
dwEscaped=INTERNET_MAX_URL_LENGTH;
|
||||
|
||||
ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
|
||||
ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
|
||||
|
||||
dwEscaped = INTERNET_MAX_URL_LENGTH;
|
||||
urlW = GetWideString(szUrl);
|
||||
expected_urlW = GetWideString(szExpectUrl);
|
||||
ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
|
||||
WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
|
||||
ok(strcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
|
||||
FreeWideString(urlW);
|
||||
FreeWideString(expected_urlW);
|
||||
|
||||
}
|
||||
|
||||
static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
|
||||
{
|
||||
CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
LPWSTR wszUrl = GetWideString(szUrl);
|
||||
LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
|
||||
LPWSTR wszConvertedUrl;
|
||||
|
||||
DWORD dwSize;
|
||||
|
||||
dwSize = INTERNET_MAX_URL_LENGTH;
|
||||
ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
|
||||
ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08lx\n", dwExpectReturn);
|
||||
ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08lx Expected %s, but got %s\n", dwFlags, szExpectUrl, szReturnUrl);
|
||||
|
||||
dwSize = INTERNET_MAX_URL_LENGTH;
|
||||
ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
|
||||
ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08lx\n", dwExpectReturn);
|
||||
wszConvertedUrl = GetWideString(szReturnUrl);
|
||||
ok(strcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
|
||||
FreeWideString(wszConvertedUrl);
|
||||
|
||||
|
||||
FreeWideString(wszUrl);
|
||||
FreeWideString(wszExpectUrl);
|
||||
}
|
||||
|
||||
|
||||
static void test_UrlEscape(void)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
|
||||
test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
|
||||
TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_UrlCanonicalize(void)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
|
||||
test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
|
||||
TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
|
||||
{
|
||||
HRESULT hr;
|
||||
CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
LPWSTR wszUrl1 = GetWideString(szUrl1);
|
||||
LPWSTR wszUrl2 = GetWideString(szUrl2);
|
||||
LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
|
||||
LPWSTR wszConvertedUrl;
|
||||
|
||||
DWORD dwSize;
|
||||
DWORD dwExpectLen = lstrlen(szExpectUrl);
|
||||
|
||||
hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
|
||||
ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_INVALIDARG);
|
||||
|
||||
dwSize = 0;
|
||||
hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
|
||||
ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
|
||||
|
||||
dwSize--;
|
||||
hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
|
||||
ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
|
||||
|
||||
hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
|
||||
ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
|
||||
if(SUCCEEDED(hr)) {
|
||||
ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
|
||||
}
|
||||
|
||||
dwSize = 0;
|
||||
hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
|
||||
ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
|
||||
|
||||
dwSize--;
|
||||
hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
|
||||
ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
|
||||
|
||||
hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
|
||||
ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
|
||||
if(SUCCEEDED(hr)) {
|
||||
wszConvertedUrl = GetWideString(szReturnUrl);
|
||||
ok(strcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
|
||||
FreeWideString(wszConvertedUrl);
|
||||
}
|
||||
|
||||
FreeWideString(wszUrl1);
|
||||
FreeWideString(wszUrl2);
|
||||
FreeWideString(wszExpectUrl);
|
||||
}
|
||||
|
||||
static void test_UrlCombine(void)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
|
||||
test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
|
||||
TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_UrlCreateFromPath(void)
|
||||
{
|
||||
size_t i;
|
||||
char ret_url[INTERNET_MAX_URL_LENGTH];
|
||||
DWORD len, ret;
|
||||
WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR *pathW, *urlW;
|
||||
|
||||
for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
|
||||
len = INTERNET_MAX_URL_LENGTH;
|
||||
ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
|
||||
ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path %s\n", ret, TEST_URLFROMPATH[i].path);
|
||||
ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
|
||||
ok(len == strlen(ret_url), "ret len %ld from path %s\n", len, TEST_URLFROMPATH[i].path);
|
||||
|
||||
len = INTERNET_MAX_URL_LENGTH;
|
||||
pathW = GetWideString(TEST_URLFROMPATH[i].path);
|
||||
urlW = GetWideString(TEST_URLFROMPATH[i].url);
|
||||
ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
|
||||
ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path L\"%s\", expected %08lx\n",
|
||||
ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
|
||||
ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
|
||||
ok(len == strlenW(ret_urlW), "ret len %ld from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
|
||||
FreeWideString(urlW);
|
||||
FreeWideString(pathW);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_UrlIs(void)
|
||||
{
|
||||
BOOL ret;
|
||||
size_t i;
|
||||
WCHAR wurl[80];
|
||||
|
||||
for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
|
||||
MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
|
||||
|
||||
ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
|
||||
ok( ret == TEST_PATH_IS_URL[i].expect,
|
||||
"returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
|
||||
TEST_PATH_IS_URL[i].expect );
|
||||
|
||||
ret = UrlIsW( wurl, URLIS_URL );
|
||||
ok( ret == TEST_PATH_IS_URL[i].expect,
|
||||
"returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
|
||||
TEST_PATH_IS_URL[i].expect );
|
||||
}
|
||||
for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
|
||||
MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
|
||||
|
||||
ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
|
||||
ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
|
||||
"returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
|
||||
TEST_URLIS_ATTRIBS[i].expectOpaque );
|
||||
ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
|
||||
ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
|
||||
"returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
|
||||
TEST_URLIS_ATTRIBS[i].expectFile );
|
||||
|
||||
ret = UrlIsW( wurl, URLIS_OPAQUE);
|
||||
ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
|
||||
"returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
|
||||
TEST_URLIS_ATTRIBS[i].expectOpaque );
|
||||
ret = UrlIsW( wurl, URLIS_FILEURL);
|
||||
ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
|
||||
"returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
|
||||
TEST_URLIS_ATTRIBS[i].expectFile );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_UrlUnescape(void)
|
||||
{
|
||||
CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR *urlW, *expected_urlW;
|
||||
DWORD dwEscaped;
|
||||
size_t i;
|
||||
|
||||
for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
|
||||
dwEscaped=INTERNET_MAX_URL_LENGTH;
|
||||
ok(UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0) == S_OK, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
|
||||
ok(strcmp(szReturnUrl,TEST_URL_UNESCAPE[i].expect)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url);
|
||||
|
||||
dwEscaped = INTERNET_MAX_URL_LENGTH;
|
||||
urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
|
||||
expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
|
||||
ok(UrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0) == S_OK, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
|
||||
WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
|
||||
ok(strcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url, 0L);
|
||||
FreeWideString(urlW);
|
||||
FreeWideString(expected_urlW);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void test_PathSearchAndQualify(void)
|
||||
{
|
||||
WCHAR path1[] = {'c',':','\\','f','o','o',0};
|
||||
WCHAR expect1[] = {'c',':','\\','f','o','o',0};
|
||||
WCHAR path2[] = {'c',':','f','o','o',0};
|
||||
WCHAR c_drive[] = {'c',':',0};
|
||||
WCHAR foo[] = {'f','o','o',0};
|
||||
WCHAR path3[] = {'\\','f','o','o',0};
|
||||
WCHAR winini[] = {'w','i','n','.','i','n','i',0};
|
||||
WCHAR out[MAX_PATH];
|
||||
WCHAR cur_dir[MAX_PATH];
|
||||
WCHAR dot[] = {'.',0};
|
||||
|
||||
/* c:\foo */
|
||||
ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
|
||||
"PathSearchAndQualify rets 0\n");
|
||||
ok(!lstrcmpiW(out, expect1), "strings don't match\n");
|
||||
|
||||
/* c:foo */
|
||||
ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
|
||||
"PathSearchAndQualify rets 0\n");
|
||||
GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
|
||||
PathAddBackslashW(cur_dir);
|
||||
strcatW(cur_dir, foo);
|
||||
ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
|
||||
|
||||
/* foo */
|
||||
ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
|
||||
"PathSearchAndQualify rets 0\n");
|
||||
GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
|
||||
PathAddBackslashW(cur_dir);
|
||||
strcatW(cur_dir, foo);
|
||||
ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
|
||||
|
||||
/* \foo */
|
||||
ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
|
||||
"PathSearchAndQualify rets 0\n");
|
||||
GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
|
||||
strcpyW(cur_dir + 2, path3);
|
||||
ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
|
||||
|
||||
/* win.ini */
|
||||
ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
|
||||
"PathSearchAndQualify rets 0\n");
|
||||
if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
|
||||
GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
|
||||
ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
|
||||
|
||||
}
|
||||
|
||||
static void test_PathCreateFromUrl(void)
|
||||
{
|
||||
size_t i;
|
||||
char ret_path[INTERNET_MAX_URL_LENGTH];
|
||||
DWORD len, ret;
|
||||
WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
|
||||
WCHAR *pathW, *urlW;
|
||||
|
||||
for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
|
||||
len = INTERNET_MAX_URL_LENGTH;
|
||||
ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
|
||||
ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url);
|
||||
if(TEST_PATHFROMURL[i].path) {
|
||||
ok(!lstrcmpi(ret_path, TEST_PATHFROMURL[i].path), "got %s expected %s from url %s\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
|
||||
ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url);
|
||||
}
|
||||
len = INTERNET_MAX_URL_LENGTH;
|
||||
pathW = GetWideString(TEST_PATHFROMURL[i].path);
|
||||
urlW = GetWideString(TEST_PATHFROMURL[i].url);
|
||||
ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
|
||||
ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
|
||||
if(TEST_PATHFROMURL[i].path) {
|
||||
ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
|
||||
ok(len == strlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
|
||||
}
|
||||
FreeWideString(urlW);
|
||||
FreeWideString(pathW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_PathIsUrl(void)
|
||||
{
|
||||
size_t i;
|
||||
BOOL ret;
|
||||
|
||||
for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
|
||||
ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
|
||||
ok(ret == TEST_PATH_IS_URL[i].expect,
|
||||
"returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
|
||||
TEST_PATH_IS_URL[i].expect);
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD SHELL_charclass[] =
|
||||
{
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000080, 0x00000100, 0x00000200, 0x00000100,
|
||||
0x00000100, 0x00000100, 0x00000100, 0x00000100,
|
||||
0x00000100, 0x00000100, 0x00000002, 0x00000100,
|
||||
0x00000040, 0x00000100, 0x00000004, 0x00000000,
|
||||
0x00000100, 0x00000100, 0x00000100, 0x00000100,
|
||||
0x00000100, 0x00000100, 0x00000100, 0x00000100,
|
||||
0x00000100, 0x00000100, 0x00000010, 0x00000020,
|
||||
0x00000000, 0x00000100, 0x00000000, 0x00000001,
|
||||
0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
|
||||
0x00000008, 0x00000100, 0x00000100, 0x00000100,
|
||||
0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
|
||||
0x00000000, 0x00000100, 0x00000100
|
||||
};
|
||||
|
||||
static void test_PathIsValidCharA(void)
|
||||
{
|
||||
BOOL ret;
|
||||
unsigned int c;
|
||||
|
||||
ret = pPathIsValidCharA( 0x7f, 0 );
|
||||
ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
|
||||
|
||||
ret = pPathIsValidCharA( 0x7f, 1 );
|
||||
ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
|
||||
|
||||
for (c = 0; c < 0x7f; c++)
|
||||
{
|
||||
ret = pPathIsValidCharA( c, ~0U );
|
||||
ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
|
||||
"PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
|
||||
c, (DWORD)ret, SHELL_charclass[c] );
|
||||
}
|
||||
|
||||
for (c = 0x7f; c <= 0xff; c++)
|
||||
{
|
||||
ret = pPathIsValidCharA( c, ~0U );
|
||||
ok ( ret == 0x00000100,
|
||||
"PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x00000100\n",
|
||||
c, (DWORD)ret );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_PathIsValidCharW(void)
|
||||
{
|
||||
BOOL ret;
|
||||
unsigned int c;
|
||||
|
||||
ret = pPathIsValidCharW( 0x7f, 0 );
|
||||
ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
|
||||
|
||||
ret = pPathIsValidCharW( 0x7f, 1 );
|
||||
ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
|
||||
|
||||
for (c = 0; c < 0x7f; c++)
|
||||
{
|
||||
ret = pPathIsValidCharW( c, ~0U );
|
||||
ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
|
||||
"PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
|
||||
c, (DWORD)ret, SHELL_charclass[c] );
|
||||
}
|
||||
|
||||
for (c = 0x007f; c <= 0xffff; c++)
|
||||
{
|
||||
ret = pPathIsValidCharW( c, ~0U );
|
||||
ok ( ret == 0x00000100,
|
||||
"PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x00000100\n",
|
||||
c, (DWORD)ret );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_PathMakePretty(void)
|
||||
{
|
||||
char buff[MAX_PATH];
|
||||
|
||||
ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
|
||||
buff[0] = '\0';
|
||||
ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
|
||||
|
||||
strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
|
||||
ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
|
||||
ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
|
||||
"PathMakePretty: Long UC name not changed\n");
|
||||
|
||||
strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
|
||||
ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
|
||||
ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
|
||||
"PathMakePretty: Failed but modified path\n");
|
||||
|
||||
strcpy(buff, "TEST");
|
||||
ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
|
||||
ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
|
||||
}
|
||||
|
||||
START_TEST(path)
|
||||
{
|
||||
hShlwapi = LoadLibraryA("shlwapi.dll");
|
||||
if (!hShlwapi) return;
|
||||
|
||||
test_UrlHash();
|
||||
test_UrlGetPart();
|
||||
test_UrlCanonicalize();
|
||||
test_UrlEscape();
|
||||
test_UrlCombine();
|
||||
test_UrlCreateFromPath();
|
||||
test_UrlIs();
|
||||
test_UrlUnescape();
|
||||
|
||||
test_PathSearchAndQualify();
|
||||
test_PathCreateFromUrl();
|
||||
test_PathIsUrl();
|
||||
|
||||
test_PathMakePretty();
|
||||
|
||||
/* For whatever reason, PathIsValidCharA and PathAppendA share the same
|
||||
* ordinal number in some native versions. Check this to prevent a crash.
|
||||
*/
|
||||
pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
|
||||
if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
|
||||
{
|
||||
test_PathIsValidCharA();
|
||||
|
||||
pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
|
||||
if (pPathIsValidCharW) test_PathIsValidCharW();
|
||||
}
|
||||
}
|
13
reactos/regtests/winetests/shlwapi/shlwapi_test.xml
Executable file
13
reactos/regtests/winetests/shlwapi/shlwapi_test.xml
Executable file
|
@ -0,0 +1,13 @@
|
|||
<module name="shlwapi_test" type="win32cui" installbase="bin" installname="shlwapi_test.exe" warnings="true">
|
||||
<include base="shlwapi_test">.</include>
|
||||
<define name="__USE_W32API" />
|
||||
<library>ntdll</library>
|
||||
<library>shlwapi</library>
|
||||
<library>ole32</library>
|
||||
<library>oleaut32</library>
|
||||
<file>clist.c</file>
|
||||
<file>ordinal.c</file>
|
||||
<file>shreg.c</file>
|
||||
<file>string.c</file>
|
||||
<file>testlist.c</file>
|
||||
</module>
|
385
reactos/regtests/winetests/shlwapi/shreg.c
Executable file
385
reactos/regtests/winetests/shlwapi/shreg.c
Executable file
|
@ -0,0 +1,385 @@
|
|||
/* Unit test suite for SHReg* functions
|
||||
*
|
||||
* Copyright 2002 Juergen Schmied
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "winuser.h"
|
||||
#include "shlwapi.h"
|
||||
|
||||
/* Keys used for testing */
|
||||
#define REG_TEST_KEY "Software\\Wine\\Test"
|
||||
#define REG_CURRENT_VERSION "Software\\Microsoft\\Windows\\CurrentVersion"
|
||||
|
||||
static HMODULE hshlwapi;
|
||||
typedef DWORD (WINAPI *SHCopyKeyA_func)(HKEY,LPCSTR,HKEY,DWORD);
|
||||
static SHCopyKeyA_func pSHCopyKeyA;
|
||||
typedef DWORD (WINAPI *SHRegGetPathA_func)(HKEY,LPCSTR,LPCSTR,LPSTR,DWORD);
|
||||
static SHRegGetPathA_func pSHRegGetPathA;
|
||||
|
||||
static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";
|
||||
static const char * sTestpath2 = "%FOO%\\subdir1";
|
||||
|
||||
static const char * sEnvvar1 = "bar";
|
||||
static const char * sEnvvar2 = "ImARatherLongButIndeedNeededString";
|
||||
|
||||
static char sExpTestpath1[MAX_PATH];
|
||||
static char sExpTestpath2[MAX_PATH];
|
||||
static unsigned sExpLen1;
|
||||
static unsigned sExpLen2;
|
||||
|
||||
static const char * sEmptyBuffer ="0123456789";
|
||||
|
||||
/* delete key and all its subkeys */
|
||||
static DWORD delete_key( HKEY hkey, LPSTR parent, LPSTR keyname )
|
||||
{
|
||||
HKEY parentKey;
|
||||
DWORD ret;
|
||||
|
||||
RegCloseKey(hkey);
|
||||
|
||||
/* open the parent of the key to close */
|
||||
ret = RegOpenKeyExA( HKEY_CURRENT_USER, parent, 0, KEY_ALL_ACCESS, &parentKey);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = SHDeleteKeyA( parentKey, keyname );
|
||||
RegCloseKey(parentKey);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HKEY create_test_entries(void)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD ret;
|
||||
|
||||
SetEnvironmentVariableA("LONGSYSTEMVAR", sEnvvar1);
|
||||
SetEnvironmentVariableA("FOO", sEnvvar2);
|
||||
|
||||
ret = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKey);
|
||||
ok( ERROR_SUCCESS == ret, "RegCreateKeyA failed, ret=%lu\n", ret);
|
||||
|
||||
if (hKey)
|
||||
{
|
||||
ok(!RegSetValueExA(hKey,"Test1",0,REG_EXPAND_SZ, (LPBYTE) sTestpath1, strlen(sTestpath1)+1), "RegSetValueExA failed\n");
|
||||
ok(!RegSetValueExA(hKey,"Test2",0,REG_SZ, (LPBYTE) sTestpath1, strlen(sTestpath1)+1), "RegSetValueExA failed\n");
|
||||
ok(!RegSetValueExA(hKey,"Test3",0,REG_EXPAND_SZ, (LPBYTE) sTestpath2, strlen(sTestpath2)+1), "RegSetValueExA failed\n");
|
||||
}
|
||||
|
||||
sExpLen1 = ExpandEnvironmentStringsA(sTestpath1, sExpTestpath1, sizeof(sExpTestpath1));
|
||||
sExpLen2 = ExpandEnvironmentStringsA(sTestpath2, sExpTestpath2, sizeof(sExpTestpath2));
|
||||
|
||||
ok(sExpLen1 > 0, "Couldn't expand %s\n", sTestpath1);
|
||||
trace("sExplen1 = (%d)\n", sExpLen1);
|
||||
ok(sExpLen2 > 0, "Couldn't expand %s\n", sTestpath2);
|
||||
trace("sExplen2 = (%d)\n", sExpLen2);
|
||||
|
||||
return hKey;
|
||||
}
|
||||
|
||||
static void test_SHGetValue(void)
|
||||
{
|
||||
DWORD dwSize;
|
||||
DWORD dwType;
|
||||
DWORD dwRet;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = MAX_PATH;
|
||||
dwType = -1;
|
||||
dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", &dwType, buf, &dwSize);
|
||||
ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%lu\n", dwRet);
|
||||
ok( 0 == strcmp(sExpTestpath1, buf), "Comparing of (%s) with (%s) failed\n", buf, sExpTestpath1);
|
||||
ok( REG_SZ == dwType, "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = MAX_PATH;
|
||||
dwType = -1;
|
||||
dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", &dwType, buf, &dwSize);
|
||||
ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%lu\n", dwRet);
|
||||
ok( 0 == strcmp(sTestpath1, buf) , "Comparing of (%s) with (%s) failed\n", buf, sTestpath1);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
}
|
||||
|
||||
static void test_SHGetRegPath(void)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
DWORD dwRet;
|
||||
|
||||
if (!pSHRegGetPathA)
|
||||
return;
|
||||
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwRet = (*pSHRegGetPathA)(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", buf, 0);
|
||||
ok( ERROR_SUCCESS == dwRet, "SHRegGetPathA failed, ret=%lu\n", dwRet);
|
||||
ok( 0 == strcmp(sExpTestpath1, buf) , "Comparing (%s) with (%s) failed\n", buf, sExpTestpath1);
|
||||
}
|
||||
|
||||
static void test_SHQUeryValueEx(void)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwSize;
|
||||
DWORD dwType;
|
||||
char buf[MAX_PATH];
|
||||
DWORD dwRet;
|
||||
const char * sTestedFunction = "";
|
||||
DWORD nUsedBuffer1,nUsedBuffer2;
|
||||
|
||||
sTestedFunction = "RegOpenKeyExA";
|
||||
dwRet = RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_KEY, 0, KEY_QUERY_VALUE, &hKey);
|
||||
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
|
||||
|
||||
/****** SHQueryValueExA ******/
|
||||
|
||||
sTestedFunction = "SHQueryValueExA";
|
||||
nUsedBuffer1 = max(strlen(sExpTestpath1)+1, strlen(sTestpath1)+1);
|
||||
nUsedBuffer2 = max(strlen(sExpTestpath2)+1, strlen(sTestpath2)+1);
|
||||
/*
|
||||
* Case 1.1 All arguments are NULL
|
||||
*/
|
||||
dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, NULL);
|
||||
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
|
||||
|
||||
/*
|
||||
* Case 1.2 dwType is set
|
||||
*/
|
||||
dwType = -1;
|
||||
dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, NULL, NULL);
|
||||
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
/*
|
||||
* dwSize is set
|
||||
* dwExpanded < dwUnExpanded
|
||||
*/
|
||||
dwSize = 6;
|
||||
dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, &dwSize);
|
||||
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
|
||||
ok( dwSize == nUsedBuffer1, "Buffer sizes (%lu) and (%lu) are not equal\n", dwSize, nUsedBuffer1);
|
||||
|
||||
/*
|
||||
* dwExpanded > dwUnExpanded
|
||||
*/
|
||||
dwSize = 6;
|
||||
dwRet = SHQueryValueExA( hKey, "Test3", NULL, NULL, NULL, &dwSize);
|
||||
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
|
||||
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
|
||||
|
||||
/*
|
||||
* Case 1 string shrinks during expanding
|
||||
*/
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = 6;
|
||||
dwType = -1;
|
||||
dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, buf, &dwSize);
|
||||
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
|
||||
ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer);
|
||||
ok( dwSize == nUsedBuffer1, "Buffer sizes (%lu) and (%lu) are not equal\n", dwSize, nUsedBuffer1);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
/*
|
||||
* string grows during expanding
|
||||
* dwSize is smaller then the size of the unexpanded string
|
||||
*/
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = 6;
|
||||
dwType = -1;
|
||||
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize);
|
||||
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
|
||||
ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer);
|
||||
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
/*
|
||||
* string grows during expanding
|
||||
* dwSize is larger then the size of the unexpanded string but smaller than the part before the backslash
|
||||
* if the unexpanded string fits into the buffer it can get cut when expanded
|
||||
*/
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = strlen(sEnvvar2) - 2;
|
||||
dwType = -1;
|
||||
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize);
|
||||
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
|
||||
|
||||
todo_wine
|
||||
{
|
||||
ok( (0 == strcmp("", buf)) | (0 == strcmp(sTestpath2, buf)),
|
||||
"Expected empty or unexpanded string (win98), got (%s)\n", buf);
|
||||
}
|
||||
|
||||
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
/*
|
||||
* string grows during expanding
|
||||
* dwSize is larger then the size of the part before the backslash but smaller then the expanded string
|
||||
* if the unexpanded string fits into the buffer it can get cut when expanded
|
||||
*/
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = sExpLen2 - 4;
|
||||
dwType = -1;
|
||||
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize);
|
||||
ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
|
||||
|
||||
todo_wine
|
||||
{
|
||||
ok( (0 == strcmp("", buf)) | (0 == strcmp(sEnvvar2, buf)),
|
||||
"Expected empty or first part of the string \"%s\", got \"%s\"\n", sEnvvar2, buf);
|
||||
}
|
||||
|
||||
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
/*
|
||||
* The buffer is NULL but the size is set
|
||||
*/
|
||||
strcpy(buf, sEmptyBuffer);
|
||||
dwSize = 6;
|
||||
dwType = -1;
|
||||
dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, NULL, &dwSize);
|
||||
ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet);
|
||||
ok( dwSize >= nUsedBuffer2, "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2);
|
||||
ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType);
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
static void test_SHCopyKey(void)
|
||||
{
|
||||
HKEY hKeySrc, hKeyDst;
|
||||
DWORD dwRet;
|
||||
|
||||
/* Delete existing destination sub keys */
|
||||
hKeyDst = NULL;
|
||||
if (!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst) && hKeyDst)
|
||||
{
|
||||
SHDeleteKeyA(hKeyDst, NULL);
|
||||
RegCloseKey(hKeyDst);
|
||||
}
|
||||
|
||||
hKeyDst = NULL;
|
||||
dwRet = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst);
|
||||
if (dwRet || !hKeyDst)
|
||||
{
|
||||
ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%lu)\n", dwRet);
|
||||
return;
|
||||
}
|
||||
|
||||
hKeySrc = NULL;
|
||||
dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION, &hKeySrc);
|
||||
if (dwRet || !hKeySrc)
|
||||
{
|
||||
ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%lu)\n", dwRet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (pSHCopyKeyA)
|
||||
{
|
||||
dwRet = (*pSHCopyKeyA)(hKeySrc, NULL, hKeyDst, 0);
|
||||
ok ( ERROR_SUCCESS == dwRet, "Copy failed, ret=(%lu)\n", dwRet);
|
||||
}
|
||||
|
||||
RegCloseKey(hKeySrc);
|
||||
RegCloseKey(hKeyDst);
|
||||
|
||||
/* Check we copied the sub keys, i.e. something that's on every windows system (including Wine) */
|
||||
hKeyDst = NULL;
|
||||
dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination\\Setup", &hKeyDst);
|
||||
if (dwRet || !hKeyDst)
|
||||
{
|
||||
ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%lu)\n", dwRet);
|
||||
return;
|
||||
}
|
||||
|
||||
/* And the we copied the values too */
|
||||
ok(!SHQueryValueExA(hKeyDst, "BootDir", NULL, NULL, NULL, NULL), "SHQueryValueExA failed\n");
|
||||
|
||||
RegCloseKey(hKeyDst);
|
||||
}
|
||||
|
||||
static void test_SHDeleteKey(void)
|
||||
{
|
||||
HKEY hKeyTest, hKeyS;
|
||||
DWORD dwRet;
|
||||
int sysfail = 1;
|
||||
|
||||
if (!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKeyTest))
|
||||
{
|
||||
if (!RegCreateKey(hKeyTest, "ODBC", &hKeyS))
|
||||
{
|
||||
HKEY hKeyO;
|
||||
|
||||
if (!RegCreateKey(hKeyS, "ODBC.INI", &hKeyO))
|
||||
{
|
||||
RegCloseKey (hKeyO);
|
||||
|
||||
if (!RegCreateKey(hKeyS, "ODBCINST.INI", &hKeyO))
|
||||
{
|
||||
RegCloseKey (hKeyO);
|
||||
sysfail = 0;
|
||||
}
|
||||
}
|
||||
RegCloseKey (hKeyS);
|
||||
}
|
||||
RegCloseKey (hKeyTest);
|
||||
}
|
||||
|
||||
if (!sysfail)
|
||||
{
|
||||
|
||||
dwRet = SHDeleteKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC");
|
||||
ok ( ERROR_SUCCESS == dwRet, "SHDeleteKey failed, ret=(%lu)\n", dwRet);
|
||||
|
||||
dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC", &hKeyS);
|
||||
ok ( ERROR_FILE_NOT_FOUND == dwRet, "SHDeleteKey did not delete\n");
|
||||
|
||||
if (dwRet == ERROR_SUCCESS)
|
||||
RegCloseKey (hKeyS);
|
||||
}
|
||||
else
|
||||
ok( 0, "Could not set up SHDeleteKey test\n");
|
||||
}
|
||||
|
||||
START_TEST(shreg)
|
||||
{
|
||||
HKEY hkey = create_test_entries();
|
||||
|
||||
if (!hkey) return;
|
||||
|
||||
hshlwapi = GetModuleHandleA("shlwapi.dll");
|
||||
if (hshlwapi)
|
||||
{
|
||||
pSHCopyKeyA=(SHCopyKeyA_func)GetProcAddress(hshlwapi,"SHCopyKeyA");
|
||||
pSHRegGetPathA=(SHRegGetPathA_func)GetProcAddress(hshlwapi,"SHRegGetPathA");
|
||||
}
|
||||
test_SHGetValue();
|
||||
test_SHQUeryValueEx();
|
||||
test_SHGetRegPath();
|
||||
test_SHCopyKey();
|
||||
test_SHDeleteKey();
|
||||
delete_key( hkey, "Software\\Wine", "Test" );
|
||||
}
|
760
reactos/regtests/winetests/shlwapi/string.c
Executable file
760
reactos/regtests/winetests/shlwapi/string.c
Executable file
|
@ -0,0 +1,760 @@
|
|||
/* Unit test suite for SHLWAPI string functions
|
||||
*
|
||||
* Copyright 2003 Jon Griffiths
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
#define NO_SHLWAPI_REG
|
||||
#define NO_SHLWAPI_PATH
|
||||
#define NO_SHLWAPI_GDI
|
||||
#define NO_SHLWAPI_STREAM
|
||||
#include "shlwapi.h"
|
||||
#include "shtypes.h"
|
||||
|
||||
static HMODULE hShlwapi;
|
||||
static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int);
|
||||
static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int);
|
||||
static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,void*,BSTR*);
|
||||
static DWORD (WINAPI *pSHAnsiToAnsi)(LPCSTR,LPSTR,int);
|
||||
static DWORD (WINAPI *pSHUnicodeToUnicode)(LPCWSTR,LPWSTR,int);
|
||||
static BOOL (WINAPI *pStrIsIntlEqualA)(BOOL,LPCSTR,LPCSTR,int);
|
||||
static BOOL (WINAPI *pIntlStrEqWorkerA)(BOOL,LPCSTR,LPCSTR,int);
|
||||
static BOOL (WINAPI *pStrIsIntlEqualW)(BOOL,LPCWSTR,LPCWSTR,int);
|
||||
static BOOL (WINAPI *pIntlStrEqWorkerW)(BOOL,LPCWSTR,LPCWSTR,int);
|
||||
|
||||
static inline int strcmpW(const WCHAR *str1, const WCHAR *str2)
|
||||
{
|
||||
while (*str1 && (*str1 == *str2)) { str1++; str2++; }
|
||||
return *str1 - *str2;
|
||||
}
|
||||
|
||||
/* StrToInt/StrToIntEx results */
|
||||
typedef struct tagStrToIntResult
|
||||
{
|
||||
const char* string;
|
||||
int str_to_int;
|
||||
int str_to_int_ex;
|
||||
int str_to_int_hex;
|
||||
} StrToIntResult;
|
||||
|
||||
static const StrToIntResult StrToInt_results[] = {
|
||||
{ "1099", 1099, 1099, 1099 },
|
||||
{ "+88987", 0, 88987, 88987 },
|
||||
{ "012", 12, 12, 12 },
|
||||
{ "-55", -55, -55, -55 },
|
||||
{ "-0", 0, 0, 0 },
|
||||
{ "0x44ff", 0, 0, 0x44ff },
|
||||
{ "+0x44f4", 0, 0, 0x44f4 },
|
||||
{ "-0x44fd", 0, 0, 0x44fd },
|
||||
{ "+ 88987", 0, 0, 0 },
|
||||
{ "- 55", 0, 0, 0 },
|
||||
{ "- 0", 0, 0, 0 },
|
||||
{ "+ 0x44f4", 0, 0, 0 },
|
||||
{ "--0x44fd", 0, 0, 0 },
|
||||
{ " 1999", 0, 1999, 1999 },
|
||||
{ " +88987", 0, 88987, 88987 },
|
||||
{ " 012", 0, 12, 12 },
|
||||
{ " -55", 0, -55, -55 },
|
||||
{ " 0x44ff", 0, 0, 0x44ff },
|
||||
{ " +0x44f4", 0, 0, 0x44f4 },
|
||||
{ " -0x44fd", 0, 0, 0x44fd },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* pStrFormatByteSize64/StrFormatKBSize results */
|
||||
typedef struct tagStrFormatSizeResult
|
||||
{
|
||||
LONGLONG value;
|
||||
const char* byte_size_64;
|
||||
const char* kb_size;
|
||||
} StrFormatSizeResult;
|
||||
|
||||
|
||||
static const StrFormatSizeResult StrFormatSize_results[] = {
|
||||
{ -1023, "-1023 bytes", "0 KB"},
|
||||
{ -24, "-24 bytes", "0 KB"},
|
||||
{ 309, "309 bytes", "1 KB"},
|
||||
{ 10191, "9.95 KB", "10 KB"},
|
||||
{ 100353, "98.0 KB", "99 KB"},
|
||||
{ 1022286, "998 KB", "999 KB"},
|
||||
{ 1046862, "0.99 MB", "1,023 KB"},
|
||||
{ 1048574619, "999 MB", "1,023,999 KB"},
|
||||
{ 1073741775, "0.99 GB", "1,048,576 KB"},
|
||||
{ ((LONGLONG)0x000000f9 << 32) | 0xfffff94e, "999 GB", "1,048,575,999 KB"},
|
||||
{ ((LONGLONG)0x000000ff << 32) | 0xfffffa9b, "0.99 TB", "1,073,741,823 KB"},
|
||||
{ ((LONGLONG)0x0003e7ff << 32) | 0xfffffa9b, "999 TB", "1,073,741,823,999 KB"},
|
||||
{ ((LONGLONG)0x0003ffff << 32) | 0xfffffbe8, "0.99 PB", "1,099,511,627,775 KB"},
|
||||
{ ((LONGLONG)0x0f9fffff << 32) | 0xfffffd35, "999 PB", "1,099,511,627,776,000 KB"},
|
||||
{ ((LONGLONG)0x0fffffff << 32) | 0xfffffa9b, "0.99 EB", "1,125,899,906,842,623 KB"},
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/* StrFormatByteSize64/StrFormatKBSize results */
|
||||
typedef struct tagStrFromTimeIntervalResult
|
||||
{
|
||||
DWORD ms;
|
||||
int digits;
|
||||
const char* time_interval;
|
||||
} StrFromTimeIntervalResult;
|
||||
|
||||
|
||||
static const StrFromTimeIntervalResult StrFromTimeInterval_results[] = {
|
||||
{ 1, 1, " 0 sec" },
|
||||
{ 1, 2, " 0 sec" },
|
||||
{ 1, 3, " 0 sec" },
|
||||
{ 1, 4, " 0 sec" },
|
||||
{ 1, 5, " 0 sec" },
|
||||
{ 1, 6, " 0 sec" },
|
||||
{ 1, 7, " 0 sec" },
|
||||
|
||||
{ 1000000, 1, " 10 min" },
|
||||
{ 1000000, 2, " 16 min" },
|
||||
{ 1000000, 3, " 16 min 40 sec" },
|
||||
{ 1000000, 4, " 16 min 40 sec" },
|
||||
{ 1000000, 5, " 16 min 40 sec" },
|
||||
{ 1000000, 6, " 16 min 40 sec" },
|
||||
{ 1000000, 7, " 16 min 40 sec" },
|
||||
|
||||
{ 1999999, 1, " 30 min" },
|
||||
{ 1999999, 2, " 33 min" },
|
||||
{ 1999999, 3, " 33 min 20 sec" },
|
||||
{ 1999999, 4, " 33 min 20 sec" },
|
||||
{ 1999999, 5, " 33 min 20 sec" },
|
||||
{ 1999999, 6, " 33 min 20 sec" },
|
||||
{ 1999999, 7, " 33 min 20 sec" },
|
||||
|
||||
{ 3999997, 1, " 1 hr" },
|
||||
{ 3999997, 2, " 1 hr 6 min" },
|
||||
{ 3999997, 3, " 1 hr 6 min 40 sec" },
|
||||
{ 3999997, 4, " 1 hr 6 min 40 sec" },
|
||||
{ 3999997, 5, " 1 hr 6 min 40 sec" },
|
||||
{ 3999997, 6, " 1 hr 6 min 40 sec" },
|
||||
{ 3999997, 7, " 1 hr 6 min 40 sec" },
|
||||
|
||||
{ 149999851, 7, " 41 hr 40 min 0 sec" },
|
||||
{ 150999850, 1, " 40 hr" },
|
||||
{ 150999850, 2, " 41 hr" },
|
||||
{ 150999850, 3, " 41 hr 50 min" },
|
||||
{ 150999850, 4, " 41 hr 56 min" },
|
||||
{ 150999850, 5, " 41 hr 56 min 40 sec" },
|
||||
{ 150999850, 6, " 41 hr 56 min 40 sec" },
|
||||
{ 150999850, 7, " 41 hr 56 min 40 sec" },
|
||||
|
||||
{ 493999507, 1, " 100 hr" },
|
||||
{ 493999507, 2, " 130 hr" },
|
||||
{ 493999507, 3, " 137 hr" },
|
||||
{ 493999507, 4, " 137 hr 10 min" },
|
||||
{ 493999507, 5, " 137 hr 13 min" },
|
||||
{ 493999507, 6, " 137 hr 13 min 20 sec" },
|
||||
{ 493999507, 7, " 137 hr 13 min 20 sec" },
|
||||
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
static void test_StrChrA(void)
|
||||
{
|
||||
char string[129];
|
||||
WORD count;
|
||||
|
||||
/* this test crashes on win2k SP4 */
|
||||
/*ok(!StrChrA(NULL,'\0'), "found a character in a NULL string!\n");*/
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
string[count] = (char)count;
|
||||
string[128] = '\0';
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPSTR result = StrChrA(string+32, count);
|
||||
ok(result - string == count,
|
||||
"found char '%c' in wrong place: got %d, expected %d\n",
|
||||
count, result - string, count);
|
||||
}
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPSTR result = StrChrA(string+count+1, count);
|
||||
ok(!result, "found char '%c' not in the string\n", count);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrChrW(void)
|
||||
{
|
||||
WCHAR string[16385];
|
||||
WORD count;
|
||||
|
||||
/* this test crashes on win2k SP4 */
|
||||
/*ok(!StrChrW(NULL,'\0'), "found a character in a NULL string!\n");*/
|
||||
|
||||
for (count = 32; count < 16384; count++)
|
||||
string[count] = count;
|
||||
string[16384] = '\0';
|
||||
|
||||
for (count = 32; count < 16384; count++)
|
||||
{
|
||||
LPWSTR result = StrChrW(string+32, count);
|
||||
ok((result - string) == count, "found char %d in wrong place\n", count);
|
||||
}
|
||||
|
||||
for (count = 32; count < 16384; count++)
|
||||
{
|
||||
LPWSTR result = StrChrW(string+count+1, count);
|
||||
ok(!result, "found char not in the string\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrChrIA(void)
|
||||
{
|
||||
char string[129];
|
||||
WORD count;
|
||||
|
||||
/* this test crashes on win2k SP4 */
|
||||
/*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!\n");*/
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
string[count] = (char)count;
|
||||
string[128] = '\0';
|
||||
|
||||
for (count = 'A'; count <= 'X'; count++)
|
||||
{
|
||||
LPSTR result = StrChrIA(string+32, count);
|
||||
|
||||
ok(result - string == count, "found char '%c' in wrong place\n", count);
|
||||
ok(StrChrIA(result, count)!=NULL, "didn't find lowercase '%c'\n", count);
|
||||
}
|
||||
|
||||
for (count = 'a'; count < 'z'; count++)
|
||||
{
|
||||
LPSTR result = StrChrIA(string+count+1, count);
|
||||
ok(!result, "found char not in the string\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrChrIW(void)
|
||||
{
|
||||
WCHAR string[129];
|
||||
WORD count;
|
||||
|
||||
/* this test crashes on win2k SP4 */
|
||||
/*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!\n");*/
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
string[count] = count;
|
||||
string[128] = '\0';
|
||||
|
||||
for (count = 'A'; count <= 'X'; count++)
|
||||
{
|
||||
LPWSTR result = StrChrIW(string+32, count);
|
||||
|
||||
ok(result - string == count, "found char '%c' in wrong place\n", count);
|
||||
ok(StrChrIW(result, count)!=NULL, "didn't find lowercase '%c'\n", count);
|
||||
}
|
||||
|
||||
for (count = 'a'; count < 'z'; count++)
|
||||
{
|
||||
LPWSTR result = StrChrIW(string+count+1, count);
|
||||
ok(!result, "found char not in the string\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrRChrA(void)
|
||||
{
|
||||
char string[129];
|
||||
WORD count;
|
||||
|
||||
/* this test crashes on win2k SP4 */
|
||||
/*ok(!StrRChrA(NULL, NULL,'\0'), "found a character in a NULL string!\n");*/
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
string[count] = (char)count;
|
||||
string[128] = '\0';
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPSTR result = StrRChrA(string+32, NULL, count);
|
||||
ok(result - string == count, "found char %d in wrong place\n", count);
|
||||
}
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPSTR result = StrRChrA(string+count+1, NULL, count);
|
||||
ok(!result, "found char not in the string\n");
|
||||
}
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPSTR result = StrRChrA(string+count+1, string + 127, count);
|
||||
ok(!result, "found char not in the string\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrRChrW(void)
|
||||
{
|
||||
WCHAR string[129];
|
||||
WORD count;
|
||||
|
||||
/* this test crashes on win2k SP4 */
|
||||
/*ok(!StrRChrW(NULL, NULL,'\0'), "found a character in a NULL string!\n");*/
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
string[count] = count;
|
||||
string[128] = '\0';
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPWSTR result = StrRChrW(string+32, NULL, count);
|
||||
ok(result - string == count,
|
||||
"found char %d in wrong place: got %d, expected %d\n",
|
||||
count, result - string, count);
|
||||
}
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPWSTR result = StrRChrW(string+count+1, NULL, count);
|
||||
ok(!result, "found char %d not in the string\n", count);
|
||||
}
|
||||
|
||||
for (count = 32; count < 128; count++)
|
||||
{
|
||||
LPWSTR result = StrRChrW(string+count+1, string + 127, count);
|
||||
ok(!result, "found char %d not in the string\n", count);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrCpyW(void)
|
||||
{
|
||||
WCHAR szSrc[256];
|
||||
WCHAR szBuff[256];
|
||||
const StrFormatSizeResult* result = StrFormatSize_results;
|
||||
|
||||
|
||||
while(result->value)
|
||||
{
|
||||
MultiByteToWideChar(0,0,result->byte_size_64,-1,szSrc,sizeof(szSrc)/sizeof(WCHAR));
|
||||
|
||||
StrCpyW(szBuff, szSrc);
|
||||
ok(!StrCmpW(szSrc, szBuff), "Copied string %s wrong\n", result->byte_size_64);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_StrToIntA(void)
|
||||
{
|
||||
const StrToIntResult *result = StrToInt_results;
|
||||
int return_val;
|
||||
|
||||
while (result->string)
|
||||
{
|
||||
return_val = StrToIntA(result->string);
|
||||
ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
|
||||
result->string, return_val);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrToIntW(void)
|
||||
{
|
||||
WCHAR szBuff[256];
|
||||
const StrToIntResult *result = StrToInt_results;
|
||||
int return_val;
|
||||
|
||||
while (result->string)
|
||||
{
|
||||
MultiByteToWideChar(0,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
|
||||
return_val = StrToIntW(szBuff);
|
||||
ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
|
||||
result->string, return_val);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrToIntExA(void)
|
||||
{
|
||||
const StrToIntResult *result = StrToInt_results;
|
||||
int return_val;
|
||||
BOOL bRet;
|
||||
|
||||
while (result->string)
|
||||
{
|
||||
return_val = -1;
|
||||
bRet = StrToIntExA(result->string,0,&return_val);
|
||||
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
|
||||
result->string);
|
||||
if (bRet)
|
||||
ok(return_val == result->str_to_int_ex, "converted '%s' wrong (%d)\n",
|
||||
result->string, return_val);
|
||||
result++;
|
||||
}
|
||||
|
||||
result = StrToInt_results;
|
||||
while (result->string)
|
||||
{
|
||||
return_val = -1;
|
||||
bRet = StrToIntExA(result->string,STIF_SUPPORT_HEX,&return_val);
|
||||
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
|
||||
result->string);
|
||||
if (bRet)
|
||||
ok(return_val == result->str_to_int_hex, "converted '%s' wrong (%d)\n",
|
||||
result->string, return_val);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrToIntExW(void)
|
||||
{
|
||||
WCHAR szBuff[256];
|
||||
const StrToIntResult *result = StrToInt_results;
|
||||
int return_val;
|
||||
BOOL bRet;
|
||||
|
||||
while (result->string)
|
||||
{
|
||||
return_val = -1;
|
||||
MultiByteToWideChar(0,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
|
||||
bRet = StrToIntExW(szBuff, 0, &return_val);
|
||||
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
|
||||
result->string);
|
||||
if (bRet)
|
||||
ok(return_val == result->str_to_int_ex, "converted '%s' wrong (%d)\n",
|
||||
result->string, return_val);
|
||||
result++;
|
||||
}
|
||||
|
||||
result = StrToInt_results;
|
||||
while (result->string)
|
||||
{
|
||||
return_val = -1;
|
||||
MultiByteToWideChar(0,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
|
||||
bRet = StrToIntExW(szBuff, STIF_SUPPORT_HEX, &return_val);
|
||||
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
|
||||
result->string);
|
||||
if (bRet)
|
||||
ok(return_val == result->str_to_int_hex, "converted '%s' wrong (%d)\n",
|
||||
result->string, return_val);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrDupA(void)
|
||||
{
|
||||
LPSTR lpszStr;
|
||||
const StrFormatSizeResult* result = StrFormatSize_results;
|
||||
|
||||
while(result->value)
|
||||
{
|
||||
lpszStr = StrDupA(result->byte_size_64);
|
||||
|
||||
ok(lpszStr != NULL, "Dup failed\n");
|
||||
if (lpszStr)
|
||||
{
|
||||
ok(!strcmp(result->byte_size_64, lpszStr), "Copied string wrong\n");
|
||||
LocalFree((HLOCAL)lpszStr);
|
||||
}
|
||||
result++;
|
||||
}
|
||||
|
||||
/* Later versions of shlwapi return NULL for this, but earlier versions
|
||||
* returned an empty string (as Wine does).
|
||||
*/
|
||||
lpszStr = StrDupA(NULL);
|
||||
ok(lpszStr == NULL || *lpszStr == '\0', "NULL string returned %p\n", lpszStr);
|
||||
}
|
||||
|
||||
static void test_StrFormatByteSize64A(void)
|
||||
{
|
||||
char szBuff[256];
|
||||
const StrFormatSizeResult* result = StrFormatSize_results;
|
||||
|
||||
while(result->value)
|
||||
{
|
||||
StrFormatByteSize64A(result->value, szBuff, 256);
|
||||
|
||||
ok(!strcmp(result->byte_size_64, szBuff),
|
||||
"Formatted %lx%08lx wrong: got %s, expected %s\n",
|
||||
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->byte_size_64);
|
||||
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrFormatKBSizeW(void)
|
||||
{
|
||||
WCHAR szBuffW[256];
|
||||
char szBuff[256];
|
||||
const StrFormatSizeResult* result = StrFormatSize_results;
|
||||
|
||||
while(result->value)
|
||||
{
|
||||
StrFormatKBSizeW(result->value, szBuffW, 256);
|
||||
WideCharToMultiByte(0,0,szBuffW,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR),0,0);
|
||||
ok(!strcmp(result->kb_size, szBuff),
|
||||
"Formatted %lx%08lx wrong: got %s, expected %s\n",
|
||||
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->kb_size);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrFormatKBSizeA(void)
|
||||
{
|
||||
char szBuff[256];
|
||||
const StrFormatSizeResult* result = StrFormatSize_results;
|
||||
|
||||
while(result->value)
|
||||
{
|
||||
StrFormatKBSizeA(result->value, szBuff, 256);
|
||||
|
||||
ok(!strcmp(result->kb_size, szBuff),
|
||||
"Formatted %lx%08lx wrong: got %s, expected %s\n",
|
||||
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->kb_size);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrFromTimeIntervalA(void)
|
||||
{
|
||||
char szBuff[256];
|
||||
const StrFromTimeIntervalResult* result = StrFromTimeInterval_results;
|
||||
|
||||
while(result->ms)
|
||||
{
|
||||
StrFromTimeIntervalA(szBuff, 256, result->ms, result->digits);
|
||||
|
||||
ok(!strcmp(result->time_interval, szBuff), "Formatted %ld %d wrong\n",
|
||||
result->ms, result->digits);
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_StrCmpA(void)
|
||||
{
|
||||
static const char str1[] = {'a','b','c','d','e','f'};
|
||||
static const char str2[] = {'a','B','c','d','e','f'};
|
||||
ok(0 != StrCmpNA(str1, str2, 6), "StrCmpNA is case-insensitive\n");
|
||||
ok(0 == StrCmpNIA(str1, str2, 6), "StrCmpNIA is case-sensitive\n");
|
||||
ok(!ChrCmpIA('a', 'a'), "ChrCmpIA doesn't work at all!\n");
|
||||
ok(!ChrCmpIA('b', 'B'), "ChrCmpIA is not case-insensitive\n");
|
||||
ok(ChrCmpIA('a', 'z'), "ChrCmpIA believes that a == z!\n");
|
||||
|
||||
pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA");
|
||||
pIntlStrEqWorkerA = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerA");
|
||||
|
||||
if (!pStrIsIntlEqualA)
|
||||
return;
|
||||
|
||||
ok(pStrIsIntlEqualA(FALSE, str1, str2, 5), "StrIsIntlEqualA(FALSE,...) isn't case-insensitive\n");
|
||||
ok(!pStrIsIntlEqualA(TRUE, str1, str2, 5), "StrIsIntlEqualA(TRUE,...) isn't case-sensitive\n");
|
||||
|
||||
if (!pIntlStrEqWorkerA)
|
||||
return;
|
||||
|
||||
ok(pIntlStrEqWorkerA(FALSE, str1, str2, 5), "IntlStrEqWorkerA(FALSE,...) isn't case-insensitive\n");
|
||||
ok(!pIntlStrEqWorkerA(TRUE, str1, str2, 5), "pIntlStrEqWorkerA(TRUE,...) isn't case-sensitive\n");
|
||||
}
|
||||
|
||||
static void test_StrCmpW(void)
|
||||
{
|
||||
static const WCHAR str1[] = {'a','b','c','d','e','f'};
|
||||
static const WCHAR str2[] = {'a','B','c','d','e','f'};
|
||||
ok(0 != StrCmpNW(str1, str2, 5), "StrCmpNW is case-insensitive\n");
|
||||
ok(0 == StrCmpNIW(str1, str2, 5), "StrCmpNIW is case-sensitive\n");
|
||||
ok(!ChrCmpIW('a', 'a'), "ChrCmpIW doesn't work at all!\n");
|
||||
ok(!ChrCmpIW('b', 'B'), "ChrCmpIW is not case-insensitive\n");
|
||||
ok(ChrCmpIW('a', 'z'), "ChrCmpIW believes that a == z!\n");
|
||||
|
||||
pStrIsIntlEqualW = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualW");
|
||||
pIntlStrEqWorkerW = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerW");
|
||||
|
||||
if (!pStrIsIntlEqualW)
|
||||
return;
|
||||
|
||||
ok(pStrIsIntlEqualW(FALSE, str1, str2, 5), "StrIsIntlEqualW(FALSE,...) isn't case-insensitive\n");
|
||||
ok(!pStrIsIntlEqualW(TRUE, str1, str2, 5), "StrIsIntlEqualW(TRUE,...) isn't case-sensitive\n");
|
||||
|
||||
if (!pIntlStrEqWorkerW)
|
||||
return;
|
||||
|
||||
ok(pIntlStrEqWorkerW(FALSE, str1, str2, 5), "IntlStrEqWorkerW(FALSE,...) isn't case-insensitive\n");
|
||||
ok(!pIntlStrEqWorkerW(TRUE, str1, str2, 5), "IntlStrEqWorkerW(TRUE,...) isn't case-sensitive\n");
|
||||
}
|
||||
|
||||
static WCHAR *CoDupStrW(const char* src)
|
||||
{
|
||||
INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
|
||||
WCHAR* szTemp = (WCHAR*)CoTaskMemAlloc(len * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
|
||||
return szTemp;
|
||||
}
|
||||
|
||||
static void test_StrRetToBSTR(void)
|
||||
{
|
||||
static const WCHAR szTestW[] = { 'T','e','s','t','\0' };
|
||||
ITEMIDLIST iidl[10];
|
||||
BSTR bstr;
|
||||
STRRET strret;
|
||||
HRESULT ret;
|
||||
|
||||
pStrRetToBSTR = (void *)GetProcAddress(hShlwapi, "StrRetToBSTR");
|
||||
if (!pStrRetToBSTR) return;
|
||||
|
||||
strret.uType = STRRET_WSTR;
|
||||
strret.u.pOleStr = CoDupStrW("Test");
|
||||
bstr = 0;
|
||||
ret = pStrRetToBSTR(&strret, NULL, &bstr);
|
||||
ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW),
|
||||
"STRRET_WSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
|
||||
if (bstr)
|
||||
SysFreeString(bstr);
|
||||
|
||||
strret.uType = STRRET_CSTR;
|
||||
lstrcpyA(strret.u.cStr, "Test");
|
||||
ret = pStrRetToBSTR(&strret, NULL, &bstr);
|
||||
ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW),
|
||||
"STRRET_CSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
|
||||
if (bstr)
|
||||
SysFreeString(bstr);
|
||||
|
||||
strret.uType = STRRET_OFFSET;
|
||||
strret.u.uOffset = 1;
|
||||
strcpy((char*)&iidl, " Test");
|
||||
ret = pStrRetToBSTR(&strret, iidl, &bstr);
|
||||
ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW),
|
||||
"STRRET_OFFSET: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
|
||||
if (bstr)
|
||||
SysFreeString(bstr);
|
||||
|
||||
/* Native crashes if str is NULL */
|
||||
}
|
||||
|
||||
static void test_StrCpyNXA(void)
|
||||
{
|
||||
LPCSTR lpSrc = "hello";
|
||||
LPSTR lpszRes;
|
||||
char dest[8];
|
||||
|
||||
pStrCpyNXA = (void *)GetProcAddress(hShlwapi, (LPSTR)399);
|
||||
if (!pStrCpyNXA)
|
||||
return;
|
||||
|
||||
memset(dest, '\n', sizeof(dest));
|
||||
lpszRes = pStrCpyNXA(dest, lpSrc, sizeof(dest)/sizeof(dest[0]));
|
||||
ok(lpszRes == dest + 5 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
|
||||
"StrCpyNXA: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
|
||||
dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
|
||||
static void test_StrCpyNXW(void)
|
||||
{
|
||||
static const WCHAR lpInit[] = { '\n','\n','\n','\n','\n','\n','\n','\n' };
|
||||
static const WCHAR lpSrc[] = { 'h','e','l','l','o','\0' };
|
||||
static const WCHAR lpRes[] = { 'h','e','l','l','o','\0','\n','\n' };
|
||||
LPWSTR lpszRes;
|
||||
WCHAR dest[8];
|
||||
|
||||
pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400);
|
||||
if (!pStrCpyNXW)
|
||||
return;
|
||||
|
||||
memcpy(dest, lpInit, sizeof(lpInit));
|
||||
lpszRes = pStrCpyNXW(dest, lpSrc, sizeof(dest)/sizeof(dest[0]));
|
||||
ok(lpszRes == dest + 5 && !memcmp(dest, lpRes, sizeof(dest)),
|
||||
"StrCpyNXA: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
|
||||
dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
|
||||
static void test_SHAnsiToAnsi(void)
|
||||
{
|
||||
char dest[8];
|
||||
DWORD dwRet;
|
||||
|
||||
pSHAnsiToAnsi = (void *)GetProcAddress(hShlwapi, (LPSTR)345);
|
||||
if (!pSHAnsiToAnsi)
|
||||
return;
|
||||
|
||||
memset(dest, '\n', sizeof(dest));
|
||||
dwRet = pSHAnsiToAnsi("hello", dest, sizeof(dest)/sizeof(dest[0]));
|
||||
ok(dwRet == 6 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
|
||||
"SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
|
||||
dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
|
||||
static void test_SHUnicodeToUnicode(void)
|
||||
{
|
||||
static const WCHAR lpInit[] = { '\n','\n','\n','\n','\n','\n','\n','\n' };
|
||||
static const WCHAR lpSrc[] = { 'h','e','l','l','o','\0' };
|
||||
static const WCHAR lpRes[] = { 'h','e','l','l','o','\0','\n','\n' };
|
||||
WCHAR dest[8];
|
||||
DWORD dwRet;
|
||||
|
||||
pSHUnicodeToUnicode = (void *)GetProcAddress(hShlwapi, (LPSTR)346);
|
||||
if (!pSHUnicodeToUnicode)
|
||||
return;
|
||||
|
||||
memcpy(dest, lpInit, sizeof(lpInit));
|
||||
dwRet = pSHUnicodeToUnicode(lpSrc, dest, sizeof(dest)/sizeof(dest[0]));
|
||||
ok(dwRet == 6 && !memcmp(dest, lpRes, sizeof(dest)),
|
||||
"SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
|
||||
dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
CoInitialize(0);
|
||||
|
||||
hShlwapi = GetModuleHandleA("shlwapi");
|
||||
if (!hShlwapi)
|
||||
return;
|
||||
|
||||
test_StrChrA();
|
||||
test_StrChrW();
|
||||
test_StrChrIA();
|
||||
test_StrChrIW();
|
||||
test_StrRChrA();
|
||||
test_StrRChrW();
|
||||
test_StrCpyW();
|
||||
test_StrToIntA();
|
||||
test_StrToIntW();
|
||||
test_StrToIntExA();
|
||||
test_StrToIntExW();
|
||||
test_StrDupA();
|
||||
if (0)
|
||||
{
|
||||
/* this test fails on locales which do not use '.' as a decimal separator */
|
||||
test_StrFormatByteSize64A();
|
||||
|
||||
/* this test fails on locales which do not use '.' as a decimal separator */
|
||||
test_StrFormatKBSizeA();
|
||||
|
||||
/* FIXME: Awaiting NLS fixes in kernel before these succeed */
|
||||
test_StrFormatKBSizeW();
|
||||
}
|
||||
test_StrFromTimeIntervalA();
|
||||
test_StrCmpA();
|
||||
test_StrCmpW();
|
||||
test_StrRetToBSTR();
|
||||
test_StrCpyNXA();
|
||||
test_StrCpyNXW();
|
||||
test_SHAnsiToAnsi();
|
||||
test_SHUnicodeToUnicode();
|
||||
}
|
32
reactos/regtests/winetests/shlwapi/testlist.c
Executable file
32
reactos/regtests/winetests/shlwapi/testlist.c
Executable file
|
@ -0,0 +1,32 @@
|
|||
/* Automatically generated file; DO NOT EDIT!! */
|
||||
|
||||
/* stdarg.h is needed for Winelib */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
||||
extern void func_clist(void);
|
||||
extern void func_ordinal(void);
|
||||
extern void func_path(void);
|
||||
extern void func_shreg(void);
|
||||
extern void func_string(void);
|
||||
|
||||
struct test
|
||||
{
|
||||
const char *name;
|
||||
void (*func)(void);
|
||||
};
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "clist", func_clist },
|
||||
{ "ordinal", func_ordinal },
|
||||
{ "shreg", func_shreg },
|
||||
{ "string", func_string },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#define WINETEST_WANT_MAIN
|
||||
#include "wine/test.h"
|
Loading…
Reference in a new issue