2025-04-27 07:49:33 -04:00

270 lines
7.6 KiB
C++

#include "dirnot.h"
#include <stdio.h>
#include <dbgtrace.h>
#include <winerror.h>
#include "stdlib.h"
#include <irtlmisc.h>
#include <xmemwrpr.h>
#define NNTP_ATQ_PARAMETERS \
"System\\CurrentControlSet\\Services\\InetInfo\\Parameters"
#define MAX_INSTANCES 10
HANDLE g_heStop;
WCHAR g_szStopName[MAX_PATH];
IDirectoryNotification g_dirnot[MAX_INSTANCES];
char g_szPickupDirectory[MAX_PATH];
DWORD g_fAuto = TRUE;
DWORD g_cPreTestFiles = 100;
DWORD g_cFiles = 1000;
DWORD g_cWaitTime = 30;
DWORD g_cRetryTimeout = 5;
HRESULT __stdcall
DoNothing( IDirectoryNotification *pDirNot )
{
printf( "Got second notify with context pointer 0x%p\n", pDirNot );
return S_OK;
}
BOOL __stdcall
PrintFileName( PVOID pvContext, LPWSTR wszFileName )
{
wprintf( L"The file is %s\n", wszFileName );
return TRUE;
}
BOOL pickupfile(PVOID pContext, WCHAR *pszFilename) {
HANDLE hFile;
// try to open the file
hFile = CreateFile(pszFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
printf("%S: not found\n", pszFilename);
return TRUE;
} else {
printf("%S: in use\n", pszFilename);
return FALSE;
}
}
printf("%S: opened\n", pszFilename);
CloseHandle(hFile);
DeleteFile(pszFilename);
if (!g_fAuto && lstrcmp(pszFilename, g_szStopName) == 0) SetEvent(g_heStop);
return TRUE;
}
HRESULT startdirwatch(DWORD dwInstance, char *szPath) {
WCHAR szDirectory[MAX_PATH];
if (!MultiByteToWideChar(CP_ACP, 0, szPath, -1, szDirectory,
sizeof(szDirectory) / sizeof(WCHAR)))
{
printf("MultiByteToWideChar failed, ec = %lu", GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}
if (dwInstance == 0 && !g_fAuto) {
lstrcpy(g_szStopName, szDirectory);
lstrcat(g_szStopName, TEXT("stop"));
printf("shutdown by creating the file \"%S\"\n", g_szStopName);
}
printf("starting dirwatch instance %i on directory %S\n", dwInstance,
szDirectory);
return g_dirnot[dwInstance].Initialize( szDirectory,
NULL,
TRUE,
FILE_NOTIFY_CHANGE_SECURITY,
FILE_ACTION_MODIFIED,
PrintFileName,
DoNothing);
}
HRESULT stopdirwatch(DWORD dwInstance) {
printf("stopping dirwatch instance %i\n", dwInstance);
return g_dirnot[dwInstance].Shutdown();
}
#define INI_PICKUPDIR "PickupDirectory"
#define INI_AUTOTEST "AutoTest"
#define INI_PRETESTFILES "PreTestFilesToCreate"
#define INI_FILESTOCREATE "FilesToCreate"
#define INI_WAITTIME "TimeToWait"
#define INI_RETRYTIMEOUT "RetryTimeout"
char g_szDefaultSectionName[] = "dirwatch";
char *g_szSectionName;
int GetINIDWord(char *szINIFile, char *szKey, DWORD dwDefault) {
char szBuf[MAX_PATH];
GetPrivateProfileStringA(g_szSectionName,
szKey,
"default",
szBuf,
MAX_PATH,
szINIFile);
if (strcmp(szBuf, "default") == 0) {
return dwDefault;
} else {
return atoi(szBuf);
}
}
void ReadINIFile(char *pszINIFile) {
g_fAuto = GetINIDWord(pszINIFile, INI_AUTOTEST, g_fAuto);
g_cPreTestFiles = GetINIDWord(pszINIFile, INI_PRETESTFILES, g_cPreTestFiles);
g_cFiles = GetINIDWord(pszINIFile, INI_FILESTOCREATE, g_cFiles);
g_cWaitTime = GetINIDWord(pszINIFile, INI_WAITTIME, g_cWaitTime);
g_cRetryTimeout = GetINIDWord(pszINIFile, INI_RETRYTIMEOUT, g_cRetryTimeout);
GetPrivateProfileStringA(g_szSectionName,
INI_PICKUPDIR,
"",
g_szPickupDirectory,
MAX_PATH,
pszINIFile);
}
void CreateFiles(char *pszDirectory, char *pszBase, DWORD cFiles) {
DWORD i;
for (i = 0; i < cFiles; i++) {
HANDLE hFile;
char pszFilename[MAX_PATH];
sprintf(pszFilename, "%s%s%i", pszDirectory, pszBase, i);
hFile = CreateFileA(pszFilename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
}
}
}
DWORD NumberOfFiles(char *pszDirectory, char *pszBase) {
HANDLE hFileEnum;
char szFilename[MAX_PATH];
WIN32_FIND_DATAA finddata;
DWORD cFiles = 0;
sprintf(szFilename, "%s%s", pszDirectory, pszBase);
hFileEnum = FindFirstFileA(szFilename, &finddata);
if (hFileEnum != INVALID_HANDLE_VALUE) {
do {
printf("%s%s wasn't picked up\n", pszDirectory, finddata.cFileName);
cFiles++;
} while (FindNextFileA(hFileEnum, &finddata));
FindClose(hFileEnum);
}
return cFiles;
}
int __cdecl main(int argc, char **argv) {
HRESULT hr;
DWORD i;
_VERIFY( ExchMHeapCreate( NUM_EXCHMEM_HEAPS, 0, 100 * 1024, 0 ) );
if (argc == 2 || argc == 3) {
if (strcmp(argv[1], "/help") == 0) {
printf("usage: dirwatch [<INI file>] [<INI section>]\n");
printf(" Fields read from INI File: (section = [dirwatch])\n");
printf(" PickupDirectory (default = %s)\n", g_szPickupDirectory);
printf(" directory name should be of the form x:\\dirname\\\n");
printf(" RetryTimeout (default = %i)\n", g_cRetryTimeout);
printf(" retry time for directory notification queue\n");
printf(" AutoTest (default = %i)\n", g_fAuto);
printf(" --- the following fields are used in auto mode ---\n");
printf(" PreTestFilesToCreate (default = %i)\n", g_cPreTestFiles);
printf(" these files are created before starting pickup\n");
printf(" FilesToCreate (default = %i)\n", g_cFiles);
printf(" these files are created after starting pickup\n");
printf(" TimeToWait (default = %i)\n", g_cWaitTime);
printf(" this is the amount of time to wait for the files to be picked up\n");
return 1;
} else {
if (argc == 3) g_szSectionName = argv[2];
ReadINIFile(argv[1]);
}
}
if (*g_szPickupDirectory == 0) {
GetTempPathA(MAX_PATH, g_szPickupDirectory);
lstrcatA(g_szPickupDirectory, "dirwatch\\");
}
CreateDirectoryA(g_szPickupDirectory, NULL);
printf("parameters:\n");
printf("PickupDirectory = %s\n", g_szPickupDirectory);
printf("RetryTimeout = %i\n", g_cRetryTimeout);
printf("AutoTest = %i\n", g_fAuto);
printf("PreTestFilesToCreate = %i\n", g_cPreTestFiles);
printf("FilesToCreate = %i\n", g_cFiles);
printf("TimeToWait = %i\n\n", g_cWaitTime);
InitAsyncTrace();
InitializeIISRTL();
AtqInitialize(NULL);
hr = IDirectoryNotification::GlobalInitialize(g_cRetryTimeout, MAX_INSTANCES * 2, 1024, NULL);
if (FAILED(hr)) {
printf("IDirectoryNotification::GlobalInitialize returned hr = %08x\n", hr);
_VERIFY( ExchMHeapDestroy() );
return 0;
}
if (g_fAuto) {
CreateFiles(g_szPickupDirectory, "pre-", g_cPreTestFiles);
} else {
g_heStop = CreateEvent(NULL, FALSE, FALSE, NULL);
}
hr = startdirwatch(0, g_szPickupDirectory);
if (FAILED(hr)) {
printf("startdirwatch failed with hr = 0x%x\n", hr);
}
if (g_fAuto) {
CreateFiles(g_szPickupDirectory, "pickup-", g_cFiles);
Sleep(g_cWaitTime * 1000);
} else {
WaitForSingleObject(g_heStop, INFINITE);
}
stopdirwatch(0);
if (FAILED(hr)) {
printf("stopdirwatch failed with hr = 0x%x\n", hr);
}
hr = IDirectoryNotification::GlobalShutdown();
if (FAILED(hr)) {
printf("IDirectoryNotification::GlobalShutdown returned hr = %08x\n", hr);
}
TermAsyncTrace();
_VERIFY( ExchMHeapDestroy() );
if (g_fAuto) {
return NumberOfFiles(g_szPickupDirectory, "p*");
}
return 0;
}