You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
5.9 KiB
285 lines
5.9 KiB
#define UNICODE
|
|
#include <nt.h>
|
|
#include <ntdef.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <ntddvol.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#include "fs.h"
|
|
#include "fsp.h"
|
|
#include "fsutil.h"
|
|
#include "pipe.h"
|
|
|
|
//#define ENABLE_SMB
|
|
|
|
extern
|
|
DWORD
|
|
FindTransport(LPWSTR TransportId, LPWSTR *Transport);
|
|
|
|
extern
|
|
DWORD
|
|
SetupTree(
|
|
IN LPTSTR TreeName,
|
|
IN LPTSTR DlBuf,
|
|
IN OUT DWORD *DlBufSz,
|
|
IN LPTSTR TransportName OPTIONAL,
|
|
IN LPVOID SecurityDescriptor OPTIONAL
|
|
);
|
|
|
|
HANDLE event;
|
|
int Done = FALSE;
|
|
|
|
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
|
|
{
|
|
switch(dwCtrlType) {
|
|
case CTRL_C_EVENT:
|
|
case CTRL_BREAK_EVENT:
|
|
case CTRL_CLOSE_EVENT:
|
|
case CTRL_LOGOFF_EVENT:
|
|
case CTRL_SHUTDOWN_EVENT:
|
|
Done = TRUE;
|
|
SetEvent(event);
|
|
return TRUE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
_cdecl
|
|
main(int argc, char *argv[])
|
|
{
|
|
int cnt;
|
|
char cmd[80];
|
|
DWORD err;
|
|
WCHAR *share = L"root";
|
|
HANDLE hdl;
|
|
PVOID srvhdl, fshdl, pipehdl;
|
|
PVOID fid;
|
|
extern BOOLEAN FsReadOnly;
|
|
WCHAR *wargv[FsMaxNodes], *tmp[FsMaxNodes];
|
|
int i, mask;
|
|
LPWSTR tid;
|
|
WCHAR localname[MAX_COMPUTERNAME_LENGTH + 20];
|
|
DWORD now;
|
|
|
|
now = GetTickCount();
|
|
|
|
wcscpy(localname,L"\\\\");
|
|
err = sizeof(localname);
|
|
if (GetComputerName(&localname[wcslen(localname)], &err) == FALSE) {
|
|
return GetLastError();
|
|
}
|
|
|
|
wcscat(localname,L"$QFS\\");
|
|
wcscat(localname,share);
|
|
|
|
if (argc < 2) {
|
|
printf("Usage %s: disk1 disk2 ... diskN\n", argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
tid = NULL;
|
|
err = FindTransport(L"NetBT_Tcpip", &tid);
|
|
if (err != ERROR_SUCCESS) {
|
|
printf("Unable to find transport to bind1 %d\n", err);
|
|
return 0;
|
|
}
|
|
|
|
memset(wargv, 0, sizeof(wargv));
|
|
wargv[0] = NULL;
|
|
for (i = 1; i < argc; i++) {
|
|
int j;
|
|
wargv[i] = (WCHAR *) malloc((strlen(argv[i])+1) * sizeof(WCHAR));
|
|
j = mbstowcs(wargv[i], argv[i], strlen(argv[i]));
|
|
wargv[i][j] = L'\0';
|
|
}
|
|
|
|
FsReadOnly = TRUE;
|
|
err = FsInit(NULL, &fshdl);
|
|
if (err != STATUS_SUCCESS) {
|
|
printf("Unable to init filesystem %d\n", err);
|
|
return 0;
|
|
}
|
|
|
|
err = PipeInit(0,fshdl,&pipehdl);
|
|
if (err != STATUS_SUCCESS) {
|
|
printf("Unable to init server %d\n", err);
|
|
return 0;
|
|
}
|
|
|
|
err = SrvInit(NULL, fshdl, &srvhdl);
|
|
if (err != STATUS_SUCCESS) {
|
|
printf("Unable to init server %d\n", err);
|
|
return 0;
|
|
}
|
|
|
|
err = FsRegister(fshdl, share, wargv[1], wargv, argc-1, &fid);
|
|
if (err != STATUS_SUCCESS) {
|
|
printf("Unable to register share %d\n", err);
|
|
return 0;
|
|
}
|
|
|
|
regain:
|
|
// arb
|
|
event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
err = FsArbitrate(fid, event, &hdl);
|
|
|
|
if (err == ERROR_IO_PENDING || err == ERROR_PATH_BUSY) {
|
|
HANDLE a[2];
|
|
|
|
a[0] = hdl;
|
|
a[1] = event;
|
|
|
|
err = WaitForMultipleObjects(2, a, FALSE, 45 * 1000);
|
|
if (err != WAIT_TIMEOUT) {
|
|
// check if we got it or not
|
|
err = FsIsQuorum(fid);
|
|
} else {
|
|
// our time ran out, cancel it now
|
|
printf("Arb timedout\n");
|
|
FsCancelArbitration(fid);
|
|
err = ERROR_CANCELLED;
|
|
}
|
|
}
|
|
|
|
if (err != ERROR_SUCCESS) {
|
|
printf("Arbitration failed %d\n", err); Sleep(5*1000);
|
|
goto regain;
|
|
return 1;
|
|
}
|
|
|
|
printf("Arb in %d msec\n", GetTickCount() - now);
|
|
|
|
{
|
|
HANDLE fd;
|
|
|
|
sprintf(cmd, "\\\\?\\%s\\foo.txt", argv[1]);
|
|
fd = CreateFileA(cmd, GENERIC_READ|GENERIC_WRITE,
|
|
FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
|
|
if (fd == INVALID_HANDLE_VALUE) {
|
|
printf("Open failed %d\n", GetLastError());
|
|
}
|
|
}
|
|
// online filesystem before onlining its network name
|
|
while (FsIsOnline(fid) == ERROR_IO_PENDING)
|
|
Sleep(1*1000);
|
|
|
|
err = PipeOnline(pipehdl, share);
|
|
if (err != STATUS_SUCCESS) {
|
|
printf("Unable to online pipeserver %d\n", err);
|
|
return 0;
|
|
}
|
|
#ifdef ENABLE_SMB
|
|
// online
|
|
err = SrvOnline(srvhdl, NULL, 0);
|
|
if (err != ERROR_SUCCESS) {
|
|
printf("Srv Online failed %d\n", err);
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef ENABLE_SMB
|
|
// Now we need to connect tree
|
|
retry:
|
|
err = SetupTree(localname, NULL, NULL, tid, NULL);
|
|
if (err != ERROR_SUCCESS) {
|
|
printf("Unable to setup tree '%S' %d\n", localname, err);
|
|
if (err == ERROR_PATH_NOT_FOUND) {
|
|
Sleep(1000 * 2);
|
|
goto retry;
|
|
}
|
|
return err;
|
|
}
|
|
#endif
|
|
|
|
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
|
printf("Server is up.\n");
|
|
mask = 0x2;
|
|
while (Done == FALSE) {
|
|
int cnt;
|
|
if (FsReserve(fid) != ERROR_SUCCESS) {
|
|
printf("Lost reservation!\n");
|
|
break;
|
|
}
|
|
err = FsIsOnline(fid);
|
|
if ( err != ERROR_SUCCESS && err != ERROR_IO_PENDING) {
|
|
printf("Fs offlined %d!\n", err);
|
|
}
|
|
|
|
// Every 5 seconds change replica set
|
|
WaitForSingleObject(event, 5 * 1000);
|
|
#if 0
|
|
memset(tmp, 0, sizeof(tmp));
|
|
cnt = 0;
|
|
for (i = 1; i < argc; i++) {
|
|
if (mask & (1 << i)) {
|
|
cnt++;
|
|
printf("New replica %d '%S'\n", i, wargv[i]);
|
|
tmp[i] = wargv[i];
|
|
}
|
|
}
|
|
printf("Changing set %x size %d\n", mask, cnt);
|
|
FsUpdateReplicaSet(fid, tmp, cnt);
|
|
mask += 2;
|
|
if (cnt >= (argc - 1)) {
|
|
mask = 2;
|
|
}
|
|
#endif
|
|
}
|
|
printf("Exiting...\n");
|
|
|
|
// offline
|
|
#ifdef ENABLE_SMB
|
|
SrvOffline(srvhdl);
|
|
#endif
|
|
|
|
PipeOffline(pipehdl);
|
|
|
|
// release
|
|
FsRelease(fid);
|
|
|
|
SrvExit(srvhdl);
|
|
PipeExit(pipehdl);
|
|
FsExit(fshdl);
|
|
return 0;
|
|
}
|
|
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
|
|
void
|
|
debug_log(char *format, ...)
|
|
{
|
|
va_list marker;
|
|
|
|
va_start(marker, format);
|
|
|
|
printf("%d:%x:",GetTickCount(), GetCurrentThreadId());
|
|
vprintf(format, marker);
|
|
|
|
va_end(marker);
|
|
|
|
}
|
|
|
|
void
|
|
error_log(char *format, ...)
|
|
{
|
|
va_list marker;
|
|
|
|
va_start(marker, format);
|
|
|
|
printf("*E %d:%x:",GetTickCount(), GetCurrentThreadId());
|
|
vprintf(format, marker);
|
|
|
|
va_end(marker);
|
|
|
|
}
|
|
|
|
|