Added initial version of Delnode plus some tests.

This commit is contained in:
Sami Aario 2005-04-27 09:37:25 +00:00 committed by Alexandre Julliard
parent 86be9f20da
commit c7bd5fb16d
2 changed files with 153 additions and 8 deletions

View File

@ -2,6 +2,7 @@
* Advpack main
*
* Copyright 2004 Huw D M Davies
* Copyright 2005 Sami Aario
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -260,8 +261,71 @@ void WINAPI RegisterOCX( HWND hWnd, HINSTANCE hInst, LPCSTR cmdline, INT show )
FreeLibrary(hm);
}
static HRESULT DELNODE_recurse_dirtree(LPSTR fname, DWORD flags)
{
DWORD fattrs = GetFileAttributesA(fname);
HRESULT ret = E_FAIL;
if (fattrs & FILE_ATTRIBUTE_DIRECTORY)
{
HANDLE hFindFile;
WIN32_FIND_DATAA w32fd;
BOOL done = TRUE;
int fname_len = lstrlenA(fname);
/* Generate a path with wildcard suitable for iterating */
if (CharPrevA(fname, fname + fname_len) != "\\")
{
lstrcpyA(fname + fname_len, "\\");
++fname_len;
}
lstrcpyA(fname + fname_len, "*");
if ((hFindFile = FindFirstFileA(fname, &w32fd)) != INVALID_HANDLE_VALUE)
{
/* Iterate through the files in the directory */
for (done = FALSE; !done; done = !FindNextFileA(hFindFile, &w32fd))
{
TRACE("%s\n", w32fd.cFileName);
if (lstrcmpA(".", w32fd.cFileName) != 0 &&
lstrcmpA("..", w32fd.cFileName) != 0)
{
lstrcpyA(fname + fname_len, w32fd.cFileName);
if (DELNODE_recurse_dirtree(fname, flags) != S_OK)
{
break; /* Failure */
}
}
}
FindClose(hFindFile);
}
/* We're done with this directory, so restore the old path without wildcard */
*(fname + fname_len) = '\0';
if (done)
{
TRACE("%s: directory\n", fname);
if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && RemoveDirectoryA(fname))
{
ret = S_OK;
}
}
}
else
{
TRACE("%s: file\n", fname);
if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && DeleteFileA(fname))
{
ret = S_OK;
}
}
return ret;
}
/***********************************************************************
* DelNode (ADVPACK.@)
* DelNode (ADVPACK.@)
*
* Deletes a file or directory
*
@ -274,12 +338,26 @@ void WINAPI RegisterOCX( HWND hWnd, HINSTANCE hInst, LPCSTR cmdline, INT show )
* Failure: E_FAIL
*
* BUGS
* Unimplemented
* - Ignores flags
* - Native version apparently does a lot of checking to make sure
* we're not trying to delete a system directory etc.
*/
HRESULT WINAPI DelNode( LPCSTR pszFileOrDirName, DWORD dwFlags )
{
FIXME("(%s, 0x%08lx): stub\n", debugstr_a(pszFileOrDirName), dwFlags);
return E_FAIL;
CHAR fname[MAX_PATH];
HRESULT ret = E_FAIL;
FIXME("(%s, 0x%08lx): flags ignored\n", debugstr_a(pszFileOrDirName), dwFlags);
if (pszFileOrDirName && *pszFileOrDirName)
{
lstrcpyA(fname, pszFileOrDirName);
/* TODO: Should check for system directory deletion etc. here */
ret = DELNODE_recurse_dirtree(fname, dwFlags);
}
return ret;
}
/***********************************************************************

View File

@ -2,6 +2,7 @@
* Unit tests for advpack.dll
*
* Copyright (C) 2005 Robert Reif
* Copyright (C) 2005 Sami Aario
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,12 +21,11 @@
#include <windows.h>
#include <advpub.h>
#include <assert.h>
#include "wine/test.h"
static HRESULT (WINAPI *pGetVersionFromFile)(LPSTR,LPDWORD,LPDWORD,BOOL);
static HRESULT (WINAPI *pDelNode)(LPCSTR,DWORD);
static void version_test()
{
@ -49,6 +49,68 @@ static void version_test()
HIWORD(minor), LOWORD(minor));
}
static void delnode_test()
{
HRESULT hr;
HANDLE hn;
CHAR currDir[MAX_PATH];
int currDirLen;
/* Native DelNode apparently does not support relative paths, so we use
absolute paths for testing */
currDirLen = GetCurrentDirectoryA(sizeof(currDir) / sizeof(CHAR), currDir);
assert(currDirLen > 0 && currDirLen < sizeof(currDir) / sizeof(CHAR));
/* Simple tests; these should fail. */
hr = pDelNode(NULL, 0);
ok (hr == E_FAIL, "DelNode called with NULL pathname should return E_FAIL\n");
hr = pDelNode("", 0);
ok (hr == E_FAIL, "DelNode called with empty pathname should return E_FAIL\n");
/* Test deletion of a file. */
hn = CreateFile("DelNodeTestFile1", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hn != INVALID_HANDLE_VALUE);
CloseHandle(hn);
hr = pDelNode(lstrcat(currDir, "\\DelNodeTestFile1"), 0);
ok (hr == S_OK, "DelNode failed deleting a single file\n");
currDir[currDirLen] = '\0';
/* Test deletion of an empty directory. */
CreateDirectoryA("DelNodeTestDir", NULL);
hr = pDelNode(lstrcat(currDir, "\\DelNodeTestDir"), 0);
ok (hr == S_OK, "DelNode failed deleting an empty directory\n");
currDir[currDirLen] = '\0';
/* Test deletion of a directory containing one file. */
CreateDirectoryA("DelNodeTestDir", NULL);
hn = CreateFile("DelNodeTestDir\\DelNodeTestFile1", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hn != INVALID_HANDLE_VALUE);
CloseHandle(hn);
hr = pDelNode(lstrcat(currDir, "\\DelNodeTestDir"), 0);
ok (hr == S_OK, "DelNode failed deleting a directory containing one file\n");
currDir[currDirLen] = '\0';
/* Test deletion of a directory containing multiple files. */
CreateDirectoryA("DelNodeTestDir", NULL);
hn = CreateFile("DelNodeTestDir\\DelNodeTestFile1", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hn != INVALID_HANDLE_VALUE);
CloseHandle(hn);
hn = CreateFile("DelNodeTestDir\\DelNodeTestFile2", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hn != INVALID_HANDLE_VALUE);
CloseHandle(hn);
hn = CreateFile("DelNodeTestDir\\DelNodeTestFile3", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hn != INVALID_HANDLE_VALUE);
CloseHandle(hn);
hr = pDelNode(lstrcat(currDir, "\\DelNodeTestDir"), 0);
ok (hr == S_OK, "DelNode failed deleting a directory containing multiple files\n");
currDir[currDirLen] = '\0';
}
START_TEST(advpack)
{
HMODULE hdll;
@ -56,9 +118,14 @@ START_TEST(advpack)
hdll = LoadLibraryA("advpack.dll");
if (!hdll)
return;
pGetVersionFromFile = (void*)GetProcAddress(hdll, "GetVersionFromFile");
if (!pGetVersionFromFile)
pDelNode = (void*)GetProcAddress(hdll, "DelNode");
if (!pGetVersionFromFile || !pDelNode)
return;
version_test();
delnode_test();
FreeLibrary(hdll);
}