From fa2a988bd6676bb46d6841d171df987880af2a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=20Brant=C3=A9n?= Date: Fri, 14 Aug 2020 23:04:55 +0200 Subject: [PATCH] doc update and line ending conversions --- Ext2Srv/Ext2Pipe.cpp | 1048 +++++++++++++++--------------- Ext2Srv/Ext2Pipe.h | 96 +-- Ext2Srv/Ext2Srv.cpp | 1156 +++++++++++++++++----------------- Ext2Srv/Ext2Srv.h | 256 ++++---- Ext2Srv/Ext2Srv.rc | 250 ++++---- Ext2Srv/MAKEFILE | 22 +- Ext2Srv/Mount.cpp | 932 +++++++++++++-------------- Ext2Srv/SOURCES | 24 +- Ext2Srv/libraries/tlhelp32.h | 280 ++++---- Ext2Srv/libraries/wtsapi32.h | 354 +++++------ README.md | 6 +- 11 files changed, 2212 insertions(+), 2212 deletions(-) diff --git a/Ext2Srv/Ext2Pipe.cpp b/Ext2Srv/Ext2Pipe.cpp index b4a7be3..3d3e971 100644 --- a/Ext2Srv/Ext2Pipe.cpp +++ b/Ext2Srv/Ext2Pipe.cpp @@ -1,524 +1,524 @@ -#include -#include -#include - - -/* - * global defintions - */ - -#define CL_ASSERT(cond) do {switch('x') {case (cond): case 0: break;}} while (0) - -#define DEBUG(...) do {} while(0) - -/* - * glboal variables - */ - -BOOLEAN g_stop = FALSE; -HANDLE g_wait; - -/* pipe handles */ - -PEXT2_PIPE g_hep = NULL; - -/* - * function prototypes - */ - -BOOLEAN Ext2QueryDrive (PPIPE_REQ *pr, ULONG len); -BOOLEAN Ext2DefineDrive(PPIPE_REQ *pr, ULONG len); -BOOLEAN Ext2RemoveDrive(PPIPE_REQ *pr, ULONG len); - - -/* - * function body - */ - -BOOL Ext2ReadPipe(HANDLE p, PVOID b, DWORD c, PDWORD r) -{ - DWORD bytes = 0, total = 0; - BOOL rc = FALSE; - - while (total < c) { - rc = ReadFile(p,(PCHAR)b + total, c - total, &bytes, NULL); - if (rc) { - total += bytes; - } else { - break; - } - } - - if (r) - *r = total; - return rc; -} - - -BOOL Ext2WritePipe(HANDLE p, PVOID b, DWORD c, PDWORD w) -{ - DWORD bytes = 0, total = 0; - BOOL rc = FALSE; - - while (total < c) { - rc = WriteFile(p, (PCHAR)b + total, c - total, &bytes, NULL); - if (rc) { - total += bytes; - } else { - break; - } - } - - if (w) - *w = total; - return rc; -} - - -PSECURITY_ATTRIBUTES Ext2CreateSA() -{ - PSECURITY_ATTRIBUTES sa = NULL; - BOOL rc = FALSE; - - PSECURITY_DESCRIPTOR SD = NULL; - LPCTSTR SACL = // ("S:(ML;;NW;;;LW)") - _T("D:") // Discretionary ACL - _T("A;OICI;GA;;;BG") // Allow access to - // built-in guests - _T("A;OICI;GA;;;AN") // Allow access to - // anonymous logon - _T("A;OICI;GA;;;AU") // Allow - // read/write/execute - // to authenticated - // users - _T("A;OICI;GA;;;BA"); // Allow full control - // to administrators - - // _T("S:(ML;;NW;;;LW)D:(A;OICI;GA;;;S-1-1-0)"); - // _T("S:(ML;;NW;;;LW)D:(A;;0x12019f;;;WD)"); - - /* convert */ - rc = ConvertStringSecurityDescriptorToSecurityDescriptor( - SACL, SDDL_REVISION_1, &SD, NULL); - if (!rc) { - goto errorout; - } - - // Initialize a security attributes structure. - sa = (PSECURITY_ATTRIBUTES) LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES)); - if (NULL == sa) { - goto errorout; - } - sa->nLength = sizeof (SECURITY_ATTRIBUTES); - sa->lpSecurityDescriptor = SD; - sa->bInheritHandle = TRUE; - -errorout: - - if (!sa) { - if (SD) - LocalFree(SD); - } - - return sa; -} - -VOID Ext2FreeSA(PSECURITY_ATTRIBUTES sa) -{ - PACL ACL = NULL; - - if (NULL == sa) - return; - - if (sa->lpSecurityDescriptor) { - LocalFree(sa->lpSecurityDescriptor); - } - - LocalFree(sa); -} - -PEXT2_PIPE -Ext2CreatePipe() -{ - PEXT2_PIPE ap = NULL; - LPSECURITY_ATTRIBUTES sa = NULL; - - ap = new EXT2_PIPE; - if (!ap) { - return NULL; - } - memset(ap, 0, sizeof(EXT2_PIPE)); - - sa = Ext2CreateSA(); - - ap->p = CreateNamedPipe( _T(EXT2_MGR_SRV), PIPE_ACCESS_DUPLEX | - FILE_FLAG_WRITE_THROUGH /* | ACCESS_SYSTEM_SECURITY */, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | - PIPE_WAIT /* PIPE_REJECT_REMOTE_CLIENTS */ , - PIPE_UNLIMITED_INSTANCES, - REQ_BODY_SIZE, REQ_BODY_SIZE, - 6000, sa); - if (INVALID_HANDLE_VALUE == ap->p) { - DWORD le = GetLastError(); - if (le == ERROR_PIPE_BUSY) { - WaitNamedPipe(_T(EXT2_MGR_SRV), 1000); - } else { - } - delete ap; - ap = NULL; - goto errorout; - } - - /* create new sync event */ - ap->q = CreateEvent(NULL, TRUE, FALSE, NULL); - ap->e = CreateEvent(NULL, FALSE, FALSE, NULL); - if (INVALID_HANDLE_VALUE == ap->e || - INVALID_HANDLE_VALUE == ap->q) { - if (ap->e && INVALID_HANDLE_VALUE != ap->e) - CloseHandle(ap->e); - if (ap->q && INVALID_HANDLE_VALUE != ap->q) - CloseHandle(ap->q); - CloseHandle(ap->p); - delete ap; - ap = NULL; - goto errorout; - } - -errorout: - - if (sa) - Ext2FreeSA(sa); - - return ap; -} - - -VOID Ext2DestroyPipe(PEXT2_PIPE ap) -{ - if (ap->p && ap->p != INVALID_HANDLE_VALUE) - CloseHandle(ap->p); - - if (ap->e && ap->e != INVALID_HANDLE_VALUE) - CloseHandle(ap->e); - - if (ap->q && INVALID_HANDLE_VALUE != ap->q) - CloseHandle(ap->q); - - delete ap; -} - - -BOOLEAN Ext2QueryDrive(PPIPE_REQ *pr, ULONG len) -{ - PPIPE_REQ p; - PREQ_QUERY_DRV q; - - CHAR devPath[] = "A:"; - DWORD rc = FALSE; - - if (!pr || !*pr) - goto errorout; - - p = *pr; - q = (PREQ_QUERY_DRV)&p->data[0]; - - devPath[0] = q->drive; - q->type = GetDriveTypeA(devPath); - - if (q->type != DRIVE_NO_ROOT_DIR) { - CHAR *s = &q->name[0]; - ULONG l = len - sizeof(PIPE_REQ) - sizeof(REQ_QUERY_DRV); - rc = QueryDosDeviceA(devPath, s, l); - if (rc) { - q->result = 1; - p->len = (int)(sizeof(PIPE_REQ) + sizeof(REQ_QUERY_DRV) + strlen(s) + 1); - } else { - q->result = 0; - } - } else { - q->result = 1; - } - - -errorout: - - return TRUE; -} - - -BOOLEAN Ext2DefineDrive(PPIPE_REQ *pr, ULONG len) -{ - PPIPE_REQ p; - PREQ_DEFINE_DRV q; - BOOLEAN rc = 0; - - CHAR dosPath[] = "A:\0"; - - if (!pr || !*pr) - goto errorout; - - p = *pr; - q = (PREQ_DEFINE_DRV)&p->data[0]; - - dosPath[0] = q->drive; - q->result = (UCHAR)DefineDosDeviceA(q->flags, dosPath, &q->name[0]); - rc = (BOOLEAN) q->result; - -errorout: - - return rc; -} - -VOID Ext2NotifyDefineDrive(PPIPE_REQ pr) -{ - TCHAR task[60]; - PREQ_DEFINE_DRV q; - - if (!pr) - return; - - q = (PREQ_DEFINE_DRV)&pr->data[0]; - - if (q->result) { - _stprintf_s(task, 59, _T("/add %C"), q->drive); - Ext2NotifyUser(task, q->pid); - } -} - - -BOOLEAN Ext2RemoveDrive(PPIPE_REQ *pr, ULONG len) -{ - PPIPE_REQ p; - PREQ_REMOVE_DRV q; - BOOLEAN rc = 0; - - CHAR dosPath[] = "A:\0"; - - if (!pr || !*pr) - goto errorout; - - p = *pr; - q = (PREQ_REMOVE_DRV)&p->data[0]; - - dosPath[0] = q->drive; - q->result = (UCHAR)DefineDosDeviceA(q->flags, dosPath, &q->name[0]); - rc = (BOOLEAN)q->result; - -errorout: - - return rc; -} - -VOID Ext2NotifyRemoveDrive(PPIPE_REQ pr) -{ - TCHAR task[60]; - PREQ_REMOVE_DRV q; - - if (!pr) - return; - - q = (PREQ_REMOVE_DRV)&pr->data[0]; - - if (q->result) { - _stprintf_s(task, 59, _T("/del %C"), q->drive); - Ext2NotifyUser(task, q->pid); - } -} - -VOID __cdecl -Ext2ClientEngine(VOID *arg) -{ - PEXT2_PIPE ap = (PEXT2_PIPE)arg; - PPIPE_REQ pr = NULL; - PIPE_REQ ac; - ULONG len = 0; - BOOL rc; - - len = REQ_BODY_SIZE; - pr = (PIPE_REQ *) new CHAR[len]; - if (!pr) { - goto errorout; - } - - while (!g_stop) { - - //wait for a command - DWORD bytes=0; - - memset(&ac, 0, sizeof(ac)); - if (!Ext2ReadPipe(ap->p, &ac, sizeof(ac), &bytes)) { - break; - } - - if (ac.magic != PIPE_REQ_MAGIC || ac.len <= sizeof(ac)) { - break; - } - - if (ac.len > len) { - if (pr) - delete [] pr; - pr = (PPIPE_REQ) new CHAR[ac.len + 4]; - if (!pr) { - break; - } - len = ac.len + 4; - } - - memset(pr, 0, len); - memcpy(pr, &ac, sizeof(ac)); - if (!Ext2ReadPipe(ap->p, &pr->data[0], - ac.len - sizeof(ac), &bytes)) { - break; - } - - if (pr->cmd == CMD_QUERY_DRV) { - DEBUG("got CMD_QUERY_DRV.\n"); - rc = Ext2QueryDrive(&pr, len); - } else if (pr->cmd == CMD_DEFINE_DRV) { - DEBUG("got CMD_DEFINE_DRV.\n"); - rc = Ext2DefineDrive(&pr, len); - } else if (pr->cmd == CMD_REMOVE_DRV) { - DEBUG("got CMD_REMOVE_DRV.\n"); - rc = Ext2RemoveDrive(&pr, len); - } else { - rc = FALSE; - DEBUG("got unknown CMD.\n"); - break; - } - - if (!Ext2WritePipe(ap->p, pr, pr->len, &bytes)) { - break; - } - - if (rc) { - if (pr->cmd == CMD_REMOVE_DRV) { - Ext2NotifyRemoveDrive(pr); - } else if (pr->cmd == CMD_DEFINE_DRV) { - Ext2NotifyDefineDrive(pr); - } - } - } - - DEBUG("client disconnected.\n"); - -errorout: - - if (ap && ap->q) - SetEvent(ap->q); - - _endthread(); -} - -VOID __cdecl -Ext2PipeEngine(VOID *arg) -{ - PEXT2_PIPE ap = NULL, *cu; - DWORD le; - BOOL rc; - - DEBUG("server mode is to start...\n"); - - SetEvent(g_wait); - - while (!g_stop) { - - int times = 0; - -retry: - - /* create named pipe */ - ap = Ext2CreatePipe(); - if (NULL == ap) { - if (times++ < 10) { - Sleep(250 * times); - goto retry; - } - continue; - } - - /* ASSD_PIPE is valid or not */ - if (!ap->p || ap->p == INVALID_HANDLE_VALUE || - !ap->e || ap->e == INVALID_HANDLE_VALUE) { - Ext2DestroyPipe(ap); - if (times++ < 10) { - Sleep(500); - goto retry; - } - continue; - } - - /* wait connection request from client */ - memset(&ap->o, 0, sizeof(OVERLAPPED)); - ap->o.hEvent = ap->e; - rc = ConnectNamedPipe(ap->p, &ap->o); - le = GetLastError(); - if (rc != 0 || le == ERROR_PIPE_CONNECTED) { - DEBUG("got client connected.\n"); - ap->l = g_hep; - g_hep = ap; - _beginthread(Ext2ClientEngine, 0, (PVOID)ap); - } else { - Ext2DestroyPipe(ap); - } - - if (g_stop) - goto errorout; - - /* do cleanup of closed pipes */ - cu = &g_hep; - while (ap = *cu) { - if (ap->s) { - *cu = ap->l; - Ext2DestroyPipe(ap); - } else { - cu = &ap->l; - } - } - - DEBUG("Waiting for next client.\n"); - } - -errorout: - - SetEvent(g_wait); - _endthread(); -} - -DWORD Ext2StartPipeSrv() -{ - DWORD rc; - - do { - g_wait = CreateEvent(NULL, FALSE, FALSE, NULL); - } while (!g_wait || g_wait == INVALID_HANDLE_VALUE); - - - do { - _beginthread(Ext2PipeEngine, 0, NULL); - rc = WaitForSingleObject(g_wait, 1000*1); - } while (rc == WAIT_TIMEOUT); - - return 0; -} - -VOID Ext2StopPipeSrv() -{ - PEXT2_PIPE *cu = &g_hep, ap; - DWORD rc = 0; - - g_stop = TRUE; - - /* do cleanup of all remained pipes */ - cu = &g_hep; - while (ap = *cu) { - SetEvent(ap->e); - rc = WaitForSingleObject(ap->q, INFINITE); - if (rc != WAIT_TIMEOUT) { - *cu = ap->l; - Ext2DestroyPipe(ap); - } else { - cu = &ap->l; - } - } - WaitForSingleObject(g_wait, 1000); -} +#include +#include +#include + + +/* + * global defintions + */ + +#define CL_ASSERT(cond) do {switch('x') {case (cond): case 0: break;}} while (0) + +#define DEBUG(...) do {} while(0) + +/* + * glboal variables + */ + +BOOLEAN g_stop = FALSE; +HANDLE g_wait; + +/* pipe handles */ + +PEXT2_PIPE g_hep = NULL; + +/* + * function prototypes + */ + +BOOLEAN Ext2QueryDrive (PPIPE_REQ *pr, ULONG len); +BOOLEAN Ext2DefineDrive(PPIPE_REQ *pr, ULONG len); +BOOLEAN Ext2RemoveDrive(PPIPE_REQ *pr, ULONG len); + + +/* + * function body + */ + +BOOL Ext2ReadPipe(HANDLE p, PVOID b, DWORD c, PDWORD r) +{ + DWORD bytes = 0, total = 0; + BOOL rc = FALSE; + + while (total < c) { + rc = ReadFile(p,(PCHAR)b + total, c - total, &bytes, NULL); + if (rc) { + total += bytes; + } else { + break; + } + } + + if (r) + *r = total; + return rc; +} + + +BOOL Ext2WritePipe(HANDLE p, PVOID b, DWORD c, PDWORD w) +{ + DWORD bytes = 0, total = 0; + BOOL rc = FALSE; + + while (total < c) { + rc = WriteFile(p, (PCHAR)b + total, c - total, &bytes, NULL); + if (rc) { + total += bytes; + } else { + break; + } + } + + if (w) + *w = total; + return rc; +} + + +PSECURITY_ATTRIBUTES Ext2CreateSA() +{ + PSECURITY_ATTRIBUTES sa = NULL; + BOOL rc = FALSE; + + PSECURITY_DESCRIPTOR SD = NULL; + LPCTSTR SACL = // ("S:(ML;;NW;;;LW)") + _T("D:") // Discretionary ACL + _T("A;OICI;GA;;;BG") // Allow access to + // built-in guests + _T("A;OICI;GA;;;AN") // Allow access to + // anonymous logon + _T("A;OICI;GA;;;AU") // Allow + // read/write/execute + // to authenticated + // users + _T("A;OICI;GA;;;BA"); // Allow full control + // to administrators + + // _T("S:(ML;;NW;;;LW)D:(A;OICI;GA;;;S-1-1-0)"); + // _T("S:(ML;;NW;;;LW)D:(A;;0x12019f;;;WD)"); + + /* convert */ + rc = ConvertStringSecurityDescriptorToSecurityDescriptor( + SACL, SDDL_REVISION_1, &SD, NULL); + if (!rc) { + goto errorout; + } + + // Initialize a security attributes structure. + sa = (PSECURITY_ATTRIBUTES) LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES)); + if (NULL == sa) { + goto errorout; + } + sa->nLength = sizeof (SECURITY_ATTRIBUTES); + sa->lpSecurityDescriptor = SD; + sa->bInheritHandle = TRUE; + +errorout: + + if (!sa) { + if (SD) + LocalFree(SD); + } + + return sa; +} + +VOID Ext2FreeSA(PSECURITY_ATTRIBUTES sa) +{ + PACL ACL = NULL; + + if (NULL == sa) + return; + + if (sa->lpSecurityDescriptor) { + LocalFree(sa->lpSecurityDescriptor); + } + + LocalFree(sa); +} + +PEXT2_PIPE +Ext2CreatePipe() +{ + PEXT2_PIPE ap = NULL; + LPSECURITY_ATTRIBUTES sa = NULL; + + ap = new EXT2_PIPE; + if (!ap) { + return NULL; + } + memset(ap, 0, sizeof(EXT2_PIPE)); + + sa = Ext2CreateSA(); + + ap->p = CreateNamedPipe( _T(EXT2_MGR_SRV), PIPE_ACCESS_DUPLEX | + FILE_FLAG_WRITE_THROUGH /* | ACCESS_SYSTEM_SECURITY */, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | + PIPE_WAIT /* PIPE_REJECT_REMOTE_CLIENTS */ , + PIPE_UNLIMITED_INSTANCES, + REQ_BODY_SIZE, REQ_BODY_SIZE, + 6000, sa); + if (INVALID_HANDLE_VALUE == ap->p) { + DWORD le = GetLastError(); + if (le == ERROR_PIPE_BUSY) { + WaitNamedPipe(_T(EXT2_MGR_SRV), 1000); + } else { + } + delete ap; + ap = NULL; + goto errorout; + } + + /* create new sync event */ + ap->q = CreateEvent(NULL, TRUE, FALSE, NULL); + ap->e = CreateEvent(NULL, FALSE, FALSE, NULL); + if (INVALID_HANDLE_VALUE == ap->e || + INVALID_HANDLE_VALUE == ap->q) { + if (ap->e && INVALID_HANDLE_VALUE != ap->e) + CloseHandle(ap->e); + if (ap->q && INVALID_HANDLE_VALUE != ap->q) + CloseHandle(ap->q); + CloseHandle(ap->p); + delete ap; + ap = NULL; + goto errorout; + } + +errorout: + + if (sa) + Ext2FreeSA(sa); + + return ap; +} + + +VOID Ext2DestroyPipe(PEXT2_PIPE ap) +{ + if (ap->p && ap->p != INVALID_HANDLE_VALUE) + CloseHandle(ap->p); + + if (ap->e && ap->e != INVALID_HANDLE_VALUE) + CloseHandle(ap->e); + + if (ap->q && INVALID_HANDLE_VALUE != ap->q) + CloseHandle(ap->q); + + delete ap; +} + + +BOOLEAN Ext2QueryDrive(PPIPE_REQ *pr, ULONG len) +{ + PPIPE_REQ p; + PREQ_QUERY_DRV q; + + CHAR devPath[] = "A:"; + DWORD rc = FALSE; + + if (!pr || !*pr) + goto errorout; + + p = *pr; + q = (PREQ_QUERY_DRV)&p->data[0]; + + devPath[0] = q->drive; + q->type = GetDriveTypeA(devPath); + + if (q->type != DRIVE_NO_ROOT_DIR) { + CHAR *s = &q->name[0]; + ULONG l = len - sizeof(PIPE_REQ) - sizeof(REQ_QUERY_DRV); + rc = QueryDosDeviceA(devPath, s, l); + if (rc) { + q->result = 1; + p->len = (int)(sizeof(PIPE_REQ) + sizeof(REQ_QUERY_DRV) + strlen(s) + 1); + } else { + q->result = 0; + } + } else { + q->result = 1; + } + + +errorout: + + return TRUE; +} + + +BOOLEAN Ext2DefineDrive(PPIPE_REQ *pr, ULONG len) +{ + PPIPE_REQ p; + PREQ_DEFINE_DRV q; + BOOLEAN rc = 0; + + CHAR dosPath[] = "A:\0"; + + if (!pr || !*pr) + goto errorout; + + p = *pr; + q = (PREQ_DEFINE_DRV)&p->data[0]; + + dosPath[0] = q->drive; + q->result = (UCHAR)DefineDosDeviceA(q->flags, dosPath, &q->name[0]); + rc = (BOOLEAN) q->result; + +errorout: + + return rc; +} + +VOID Ext2NotifyDefineDrive(PPIPE_REQ pr) +{ + TCHAR task[60]; + PREQ_DEFINE_DRV q; + + if (!pr) + return; + + q = (PREQ_DEFINE_DRV)&pr->data[0]; + + if (q->result) { + _stprintf_s(task, 59, _T("/add %C"), q->drive); + Ext2NotifyUser(task, q->pid); + } +} + + +BOOLEAN Ext2RemoveDrive(PPIPE_REQ *pr, ULONG len) +{ + PPIPE_REQ p; + PREQ_REMOVE_DRV q; + BOOLEAN rc = 0; + + CHAR dosPath[] = "A:\0"; + + if (!pr || !*pr) + goto errorout; + + p = *pr; + q = (PREQ_REMOVE_DRV)&p->data[0]; + + dosPath[0] = q->drive; + q->result = (UCHAR)DefineDosDeviceA(q->flags, dosPath, &q->name[0]); + rc = (BOOLEAN)q->result; + +errorout: + + return rc; +} + +VOID Ext2NotifyRemoveDrive(PPIPE_REQ pr) +{ + TCHAR task[60]; + PREQ_REMOVE_DRV q; + + if (!pr) + return; + + q = (PREQ_REMOVE_DRV)&pr->data[0]; + + if (q->result) { + _stprintf_s(task, 59, _T("/del %C"), q->drive); + Ext2NotifyUser(task, q->pid); + } +} + +VOID __cdecl +Ext2ClientEngine(VOID *arg) +{ + PEXT2_PIPE ap = (PEXT2_PIPE)arg; + PPIPE_REQ pr = NULL; + PIPE_REQ ac; + ULONG len = 0; + BOOL rc; + + len = REQ_BODY_SIZE; + pr = (PIPE_REQ *) new CHAR[len]; + if (!pr) { + goto errorout; + } + + while (!g_stop) { + + //wait for a command + DWORD bytes=0; + + memset(&ac, 0, sizeof(ac)); + if (!Ext2ReadPipe(ap->p, &ac, sizeof(ac), &bytes)) { + break; + } + + if (ac.magic != PIPE_REQ_MAGIC || ac.len <= sizeof(ac)) { + break; + } + + if (ac.len > len) { + if (pr) + delete [] pr; + pr = (PPIPE_REQ) new CHAR[ac.len + 4]; + if (!pr) { + break; + } + len = ac.len + 4; + } + + memset(pr, 0, len); + memcpy(pr, &ac, sizeof(ac)); + if (!Ext2ReadPipe(ap->p, &pr->data[0], + ac.len - sizeof(ac), &bytes)) { + break; + } + + if (pr->cmd == CMD_QUERY_DRV) { + DEBUG("got CMD_QUERY_DRV.\n"); + rc = Ext2QueryDrive(&pr, len); + } else if (pr->cmd == CMD_DEFINE_DRV) { + DEBUG("got CMD_DEFINE_DRV.\n"); + rc = Ext2DefineDrive(&pr, len); + } else if (pr->cmd == CMD_REMOVE_DRV) { + DEBUG("got CMD_REMOVE_DRV.\n"); + rc = Ext2RemoveDrive(&pr, len); + } else { + rc = FALSE; + DEBUG("got unknown CMD.\n"); + break; + } + + if (!Ext2WritePipe(ap->p, pr, pr->len, &bytes)) { + break; + } + + if (rc) { + if (pr->cmd == CMD_REMOVE_DRV) { + Ext2NotifyRemoveDrive(pr); + } else if (pr->cmd == CMD_DEFINE_DRV) { + Ext2NotifyDefineDrive(pr); + } + } + } + + DEBUG("client disconnected.\n"); + +errorout: + + if (ap && ap->q) + SetEvent(ap->q); + + _endthread(); +} + +VOID __cdecl +Ext2PipeEngine(VOID *arg) +{ + PEXT2_PIPE ap = NULL, *cu; + DWORD le; + BOOL rc; + + DEBUG("server mode is to start...\n"); + + SetEvent(g_wait); + + while (!g_stop) { + + int times = 0; + +retry: + + /* create named pipe */ + ap = Ext2CreatePipe(); + if (NULL == ap) { + if (times++ < 10) { + Sleep(250 * times); + goto retry; + } + continue; + } + + /* ASSD_PIPE is valid or not */ + if (!ap->p || ap->p == INVALID_HANDLE_VALUE || + !ap->e || ap->e == INVALID_HANDLE_VALUE) { + Ext2DestroyPipe(ap); + if (times++ < 10) { + Sleep(500); + goto retry; + } + continue; + } + + /* wait connection request from client */ + memset(&ap->o, 0, sizeof(OVERLAPPED)); + ap->o.hEvent = ap->e; + rc = ConnectNamedPipe(ap->p, &ap->o); + le = GetLastError(); + if (rc != 0 || le == ERROR_PIPE_CONNECTED) { + DEBUG("got client connected.\n"); + ap->l = g_hep; + g_hep = ap; + _beginthread(Ext2ClientEngine, 0, (PVOID)ap); + } else { + Ext2DestroyPipe(ap); + } + + if (g_stop) + goto errorout; + + /* do cleanup of closed pipes */ + cu = &g_hep; + while (ap = *cu) { + if (ap->s) { + *cu = ap->l; + Ext2DestroyPipe(ap); + } else { + cu = &ap->l; + } + } + + DEBUG("Waiting for next client.\n"); + } + +errorout: + + SetEvent(g_wait); + _endthread(); +} + +DWORD Ext2StartPipeSrv() +{ + DWORD rc; + + do { + g_wait = CreateEvent(NULL, FALSE, FALSE, NULL); + } while (!g_wait || g_wait == INVALID_HANDLE_VALUE); + + + do { + _beginthread(Ext2PipeEngine, 0, NULL); + rc = WaitForSingleObject(g_wait, 1000*1); + } while (rc == WAIT_TIMEOUT); + + return 0; +} + +VOID Ext2StopPipeSrv() +{ + PEXT2_PIPE *cu = &g_hep, ap; + DWORD rc = 0; + + g_stop = TRUE; + + /* do cleanup of all remained pipes */ + cu = &g_hep; + while (ap = *cu) { + SetEvent(ap->e); + rc = WaitForSingleObject(ap->q, INFINITE); + if (rc != WAIT_TIMEOUT) { + *cu = ap->l; + Ext2DestroyPipe(ap); + } else { + cu = &ap->l; + } + } + WaitForSingleObject(g_wait, 1000); +} diff --git a/Ext2Srv/Ext2Pipe.h b/Ext2Srv/Ext2Pipe.h index 4b3bfbf..291739d 100644 --- a/Ext2Srv/Ext2Pipe.h +++ b/Ext2Srv/Ext2Pipe.h @@ -1,49 +1,49 @@ -#ifndef EXT2_SRV_PIPE_H -#define EXT2_SRV_PIPE_H - - -#define EXT2_MGR_SRV "\\\\.\\pipe\\EXT2MGR_PSRV" - -#define PIPE_REQ_MAGIC 0xBAD0BAD8 -#define REQ_BODY_SIZE (4096) - -#pragma pack(1) -#pragma warning(disable: 4200) - -typedef struct _PIPE_REQ { - - ULONG magic; - ULONG flag; - ULONG cmd; - ULONG len; - CHAR data[0]; -} PIPE_REQ, *PPIPE_REQ; - -#define CMD_QUERY_DRV 0xBAD00001 -#define CMD_DEFINE_DRV 0xBAD00002 -#define CMD_REMOVE_DRV 0xBAD00003 - - -typedef struct _REQ_QUERY_DRV { - ULONG type; - UCHAR drive; - UCHAR result; - USHORT symlink; - char name[0]; -} REQ_QUERY_DRV, *PREQ_QUERY_DRV; - - -typedef struct _REQ_DEFINE_DRV { - ULONG pid; - ULONG flags; - UCHAR drive; - UCHAR result; - USHORT symlink; - char name[0]; -} REQ_DEFINE_DRV, *PREQ_DEFINE_DRV, - REQ_REMOVE_DRV, *PREQ_REMOVE_DRV; - -#pragma warning(default: 4200) -#pragma pack() - +#ifndef EXT2_SRV_PIPE_H +#define EXT2_SRV_PIPE_H + + +#define EXT2_MGR_SRV "\\\\.\\pipe\\EXT2MGR_PSRV" + +#define PIPE_REQ_MAGIC 0xBAD0BAD8 +#define REQ_BODY_SIZE (4096) + +#pragma pack(1) +#pragma warning(disable: 4200) + +typedef struct _PIPE_REQ { + + ULONG magic; + ULONG flag; + ULONG cmd; + ULONG len; + CHAR data[0]; +} PIPE_REQ, *PPIPE_REQ; + +#define CMD_QUERY_DRV 0xBAD00001 +#define CMD_DEFINE_DRV 0xBAD00002 +#define CMD_REMOVE_DRV 0xBAD00003 + + +typedef struct _REQ_QUERY_DRV { + ULONG type; + UCHAR drive; + UCHAR result; + USHORT symlink; + char name[0]; +} REQ_QUERY_DRV, *PREQ_QUERY_DRV; + + +typedef struct _REQ_DEFINE_DRV { + ULONG pid; + ULONG flags; + UCHAR drive; + UCHAR result; + USHORT symlink; + char name[0]; +} REQ_DEFINE_DRV, *PREQ_DEFINE_DRV, + REQ_REMOVE_DRV, *PREQ_REMOVE_DRV; + +#pragma warning(default: 4200) +#pragma pack() + #endif // EXT2_SRV_PIPE_H \ No newline at end of file diff --git a/Ext2Srv/Ext2Srv.cpp b/Ext2Srv/Ext2Srv.cpp index 90356cb..2658d02 100644 --- a/Ext2Srv/Ext2Srv.cpp +++ b/Ext2Srv/Ext2Srv.cpp @@ -1,579 +1,579 @@ -#include - -SERVICE_STATUS ServiceStatus; -SERVICE_STATUS_HANDLE ServiceHandle; -HDEVNOTIFY ServiceNotify; - - -BOOL -Ext2ReportStatus( - DWORD State, - DWORD Exitcode, - DWORD Timeout - ) -{ - // If we're in the start state then we don't want the control manager - // sending us control messages because they'll confuse us. - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; - if (State == SERVICE_RUNNING) { - ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN | - SERVICE_ACCEPT_POWEREVENT | - SERVICE_ACCEPT_SESSIONCHANGE ; - } - - // Save the new status we've been given - ServiceStatus.dwCurrentState = State; - ServiceStatus.dwWin32ExitCode = Exitcode; - ServiceStatus.dwWaitHint = Timeout; - - // Update the checkpoint variable to let the SCM know that we - // haven't died if requests take a long time - if ((State == SERVICE_RUNNING) || (State == SERVICE_STOPPED)) { - ServiceStatus.dwCheckPoint = 0; - } else { - ServiceStatus.dwCheckPoint++; - } - - // Tell the SCM our new status - return SetServiceStatus(ServiceHandle, &ServiceStatus); -} - -void Ext2StopService() -{ - Ext2ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); - - if (ServiceNotify) { - UnregisterDeviceNotification(ServiceNotify); - ServiceNotify = NULL; - } - - /* issue stop event to main thread */ - Ext2StopPipeSrv(); - - Ext2ReportStatus(SERVICE_STOPPED, NO_ERROR, 0); -} - -VOID Ext2DrivesChangeNotify(BOOLEAN bArrival) -{ - return; -} - -VOID Ext2CleanupSession(DWORD sid) -{ -} - -DWORD WINAPI -Ext2CtrlService( - DWORD ctrlcode, DWORD dwEventType, - LPVOID lpEventData, LPVOID lpContext - ) -{ - switch(ctrlcode) - { - - case SERVICE_CONTROL_STOP: - case SERVICE_CONTROL_SHUTDOWN: - // STOP : The service must stop - Ext2StopService(); - break; - - case SERVICE_CONTROL_INTERROGATE: - // QUERY : Service control manager just wants to know our state - break; - - case SERVICE_CONTROL_DEVICEEVENT: - { - PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpEventData; - PDEV_BROADCAST_DEVICEINTERFACE lpdbi = (PDEV_BROADCAST_DEVICEINTERFACE) lpEventData; - - if (lpdbv->dbcv_devicetype != DBT_DEVTYP_VOLUME && - lpdbi->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE - ) { - break; - } - - if (dwEventType == DBT_DEVICEREMOVECOMPLETE) { - Ext2DrivesChangeNotify(FALSE); - } else if (dwEventType == DBT_DEVICEARRIVAL) { - Ext2DrivesChangeNotify(TRUE); - } - - break; - } - - case SERVICE_CONTROL_POWEREVENT: - - switch (dwEventType) { - - case PBT_APMQUERYSUSPEND: - MsgLog("Power event: PBT_APMQUERYSUSPEND.\n"); - //Ext2StartFlushThread(); - // Ext2FlushVolume(ASSDDISK_VOLUME); - break; - - case PBT_APMQUERYSUSPENDFAILED: - MsgLog("Power event: APMQUERYSUSPENDFAILED.\n"); - break; - - case PBT_APMSUSPEND: - MsgLog("Power event: PBT_APMSUSPEND.\n"); - break; - - case PBT_APMRESUMESUSPEND: - MsgLog("Power event: PBT_APMRESUMESUSPEND.\n"); - Ext2DrivesChangeNotify(TRUE); - break; - - case PBT_APMQUERYSTANDBY: - MsgLog("Power event: PBT_APMQUERYSTANDBY.\n"); - break; - - case PBT_APMQUERYSTANDBYFAILED: - MsgLog("Power event: APMQUERYSTANDBYFAILED.\n"); - break; - - case PBT_APMSTANDBY: - MsgLog("Power event: PBT_APMSTANDBY.\n"); - break; - - case PBT_APMRESUMESTANDBY: - MsgLog("Power event: PBT_APMRESUMESTANDBY.\n"); - break; - - case PBT_APMRESUMECRITICAL: - MsgLog("Power event: PBT_APMRESUMECRITICAL.\n"); - break; - - case PBT_APMPOWERSTATUSCHANGE: - MsgLog("Power event: PBT_APMPOWERSTATUSCHANGE\n"); - break; - - case PBT_APMRESUMEAUTOMATIC: - MsgLog("Power event: PBT_APMRESUMEAUTOMATIC\n"); - break; - - default: - MsgLog("Power event: unknown value %u\n", dwEventType); - break; - } - break; - - - case SERVICE_CONTROL_SESSIONCHANGE: - - switch (dwEventType) { - - case WTS_CONSOLE_CONNECT: - MsgLog("Session event: Console connected.\n"); - break; - - case WTS_CONSOLE_DISCONNECT: - MsgLog("Session event: Console disconnect.\n"); - break; - - case WTS_REMOTE_CONNECT: - MsgLog("Session event: Remote connected.\n"); - break; - - case WTS_REMOTE_DISCONNECT: - MsgLog("Session event: Remote disconnect.\n"); - break; - - case WTS_SESSION_LOCK: - MsgLog("Session event: Session locked.\n"); - break; - case WTS_SESSION_UNLOCK: - MsgLog("Session event: Session unlocked.\n"); - break; - - case WTS_SESSION_LOGON: - { - PWTSSESSION_NOTIFICATION pwn = (PWTSSESSION_NOTIFICATION)lpEventData; - MsgLog("Session event: Session logon.\n"); - Ext2StartUserTask(NULL, _T("/startmgr"), pwn->dwSessionId, FALSE); - break; - } - - case WTS_SESSION_LOGOFF: - { - PWTSSESSION_NOTIFICATION pwn = (PWTSSESSION_NOTIFICATION)lpEventData; - MsgLog("Session event: Session logoff.\n"); - if (pwn && pwn->cbSize >= sizeof(WTSSESSION_NOTIFICATION)) { - Ext2CleanupSession(pwn->dwSessionId); - } - break; - } - - default: - MsgLog("Session event: unknown value: %u.\n", dwEventType); - break; - } - break; - - case SERVICE_ACCEPT_HARDWAREPROFILECHANGE: - - default: - // Control code not recognised - break; - - } - - // Tell the control manager what we're up to. - Ext2ReportStatus(ServiceStatus.dwCurrentState, NO_ERROR, 0); - - return NO_ERROR; -} - -VOID -Ext2StartMain(VOID * arg) -{ - Ext2StartPipeSrv(); - Ext2ReportStatus(SERVICE_RUNNING, NO_ERROR, 0); -} - - -#define EXT2_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -EXT2_GUID(GUID_DEVINTERFACE_DISK, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, \ - 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); - -VOID -Ext2RegisterDeviceInterface(SERVICE_STATUS_HANDLE handle, - GUID guid, HDEVNOTIFY *notify) -{ - DEV_BROADCAST_DEVICEINTERFACE bd; - - ZeroMemory (&bd, sizeof(bd)); - bd.dbcc_size = sizeof(bd); - bd.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - bd.dbcc_classguid = guid; - *notify = RegisterDeviceNotification(handle, &bd, - DEVICE_NOTIFY_SERVICE_HANDLE); -} - - -void WINAPI -Ext2ServiceEntry(DWORD argc, char**argv) -{ - // register the service control handler - ServiceHandle = RegisterServiceCtrlHandlerEx(_T("Ext2Srv"), Ext2CtrlService, NULL); - if (ServiceHandle == 0) { - return; - } - - // setup standard service state values - ServiceStatus.dwServiceType = SERVICE_WIN32; - ServiceStatus.dwServiceSpecificExitCode = 0; - - // report our status to the SCM - Ext2ReportStatus(SERVICE_START_PENDING, NO_ERROR, 600); - - Ext2RegisterDeviceInterface(ServiceHandle, GUID_DEVINTERFACE_DISK, - &ServiceNotify); - - // Now start the service for real - Ext2StartMain(NULL); - return; -} - - -VOID -Ext2StartService(VOID *arg) -{ - SERVICE_TABLE_ENTRY Ext2SeriveTable[] = - { - {_T("Ext2Srv"), (LPSERVICE_MAIN_FUNCTION)Ext2ServiceEntry}, - {NULL, NULL} - }; - - // let service control dispatcher start Ext2Mgr - StartServiceCtrlDispatcher(Ext2SeriveTable); -} - -#define SERVICE_CMD_LENGTH MAX_PATH - -int -Ext2SetupService(BOOL bInstall) -{ - TCHAR Target[SERVICE_CMD_LENGTH]; - SC_HANDLE hService; - SC_HANDLE hManager; - - // get the filename of this executable - if (GetModuleFileName(NULL, Target, SERVICE_CMD_LENGTH - 20) == 0) { - MessageBox(NULL, _T("Ext2Srv: Unable to install as service"), NULL, - MB_OK | MB_ICONERROR); - return FALSE; - } - - // open Service Control Manager - hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if (hManager == NULL) { - MessageBox(NULL, _T("Ext2Srv: cannot open Service Control Manager"), - NULL, MB_OK | MB_ICONERROR); - return FALSE; - } - - if (bInstall) { - - // now create service entry for Ext2Mgr - hService = CreateService( - hManager, // SCManager database - _T("Ext2Srv"), // name of service - _T("Ext2Fsd Service Manager"), // name to display - SERVICE_ALL_ACCESS, // desired access - SERVICE_WIN32_OWN_PROCESS | // service type - SERVICE_INTERACTIVE_PROCESS, - SERVICE_AUTO_START, // start type - SERVICE_ERROR_NORMAL, // error control type - Target, // service's binary - NULL, // no load ordering group - NULL, // no tag identifier - NULL, // dependencies - NULL, // LocalSystem account - NULL); // no password - - if (hService == NULL) { - - DWORD error = GetLastError(); - if (error == ERROR_SERVICE_EXISTS) { - MessageBox(NULL, _T("Ext2Srv is already registered."), NULL, - MB_OK | MB_ICONERROR); - } else { - MessageBox(NULL, _T("Ext2Srv couldn't be registered."), NULL, - MB_OK | MB_ICONERROR); - } - } else { - - CloseServiceHandle(hService); - - // got Ext2Mgr installed as a service - MessageBox(NULL, _T("Ext2Srv service was successfully registered. \n\n" - "You can modify the default settings and start/stop it from Control Panel.\n" - "The service will automatically run the next time when system is restarted.\n"), - NULL, MB_OK | MB_ICONINFORMATION); - } - - } else { - - /* open the service of Pipe Event Engine */ - hService = OpenService(hManager, _T("Ext2Srv"), SERVICE_ALL_ACCESS); - - if (hService != NULL) { - - SERVICE_STATUS status; - - // stop the service - if (ControlService(hService, SERVICE_CONTROL_STOP, &status)) { - - while(QueryServiceStatus(hService, &status)) { - if (status.dwCurrentState == SERVICE_STOP_PENDING) { - Sleep(1000); - } else { - break; - } - } - - if (status.dwCurrentState != SERVICE_STOPPED) { - MessageBox(NULL, _T("Ext2Srv: service couldn't be stopped !"), - NULL, MB_OK | MB_ICONERROR); - } - } - - // remove the service from the SCM - if (DeleteService(hService)) { - MessageBox(NULL, _T("Ext2Srv: service has been unregistered."), - NULL, MB_OK | MB_ICONINFORMATION); - } else { - DWORD error = GetLastError(); - if (error == ERROR_SERVICE_MARKED_FOR_DELETE) { - MessageBox(NULL, _T("Ext2Srv: service is already unregistered"), - NULL, MB_OK | MB_ICONEXCLAMATION); - } else { - MessageBox(NULL, _T("Ext2Srv: service could not be unregistered"), - NULL, MB_OK | MB_ICONERROR); - } - } - - CloseServiceHandle(hService); - } - } - - CloseServiceHandle(hManager); - - return TRUE; -} - - -/* - * parameter process engine - */ - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int getopt(int argc, char * const argv[], const char *optstring) -{ - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - if (optreset || *place == 0) { /* update scanning pointer */ - optreset = 0; - place = argv[optind]; - if (optind >= argc || *place++ != '-') { - /* Argument is absent or is not an option */ - place = EMSG; - return (-1); - } - optopt = *place++; - if (optopt == '-' && *place == 0) { - /* "--" => end of options */ - ++optind; - place = EMSG; - return (-1); - } - if (optopt == 0) { - /* Solitary '-', treat as a '-' option - if the program (eg su) is looking for it. */ - place = EMSG; - if (strchr(optstring, '-') == NULL) - return -1; - optopt = '-'; - } - } else - optopt = *place++; - - /* See if option letter is one the caller wanted */ - if (optopt == ':' || (oli = strchr((char *)optstring, optopt)) == NULL) { - if (*place == 0) - ++optind; - if (opterr && *optstring != ':') - (void)fprintf(stderr, "unknown option -- %c\n", optopt); - return (BADCH); - } - - /* Does this option need an argument? */ - if (oli[1] != ':') { - /* don't need argument */ - optarg = NULL; - if (*place == 0) - ++optind; - } else { - /* Option-argument is either the rest of this argument or the - entire next argument. */ - if (*place) - optarg = place; - else if (argc > ++optind) - optarg = argv[optind]; - else { - /* option-argument absent */ - place = EMSG; - if (*optstring == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr,"option requires an argument - %c\n", optopt); - return (BADCH); - } - place = EMSG; - ++optind; - } - return (optopt); /* return option letter */ -} - - -void Ext2Log(DWORD ll, char *fn, int ln, char *format, ... ) -{ - va_list ap = NULL; - SYSTEMTIME st = {0}; - DWORD w = 0; - int i = 0; - CHAR s[260] = {0}; - - if (ll == EXT2_LOG_DUMP) { - /* do nothing for MsgDump */ - } else { - GetLocalTime(&st); - sprintf_s(s, 256, "%2.2u:%2.2u:%2.2u (%x): ", st.wHour, - st.wMinute, st.wSecond, GetCurrentThreadId()); - i = (int)strlen(s); - } - - /* write user message to buffer s */ - va_start(ap, format); - _vsnprintf(&s[i], 259 - i, format, ap); - va_end(ap); - - printf("%s", s); -} - - -INT __cdecl _tmain(INT argc, TCHAR *argv[]) -{ - DWORD rc = 0; - BOOL console = FALSE; - - if (argc >= 2) { - - if (0 == _tcsicmp(argv[1], _T("/installasservice"))) { - return Ext2SetupService(TRUE); - } - - if (0 == _tcsicmp(argv[1], _T("/removeservice"))) { - return Ext2SetupService(FALSE); - } - - if (0 == _tcsicmp(argv[1], _T("/startmgr"))) { - return Ext2StartMgrAsUser(); - } - - if (argc >= 4) { - - if (0 == _tcsicmp(argv[1], _T("/mount"))) { - Ext2AssignDrvLetter(argv[3], argv[2][0]); - return 0; - } - - } else if (argc >= 3) { - - if (0 == _tcsicmp(argv[1], _T("/umount"))) { - Ext2RemoveDrvLetter(argv[2][0]); - return 0; - } - - if (0 == _tcsicmp(argv[1], _T("/add"))) { - Ext2DrvNotify(argv[2][0], TRUE); - Sleep(1000); - Ext2DrvNotify(argv[2][0], TRUE); - return 0; - } - - if (0 == _tcsicmp(argv[1], _T("/del"))) { - Ext2DrvNotify(argv[2][0], FALSE); - Sleep(1000); - Ext2DrvNotify(argv[2][0], FALSE); - return 0; - } - } - } - - /* enable SE_TCB_NAME privilege */ - Ext2EnablePrivilege(SE_TCB_NAME); - - - /* service mode */ - Ext2StartService(NULL); - - return 0; +#include + +SERVICE_STATUS ServiceStatus; +SERVICE_STATUS_HANDLE ServiceHandle; +HDEVNOTIFY ServiceNotify; + + +BOOL +Ext2ReportStatus( + DWORD State, + DWORD Exitcode, + DWORD Timeout + ) +{ + // If we're in the start state then we don't want the control manager + // sending us control messages because they'll confuse us. + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + if (State == SERVICE_RUNNING) { + ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN | + SERVICE_ACCEPT_POWEREVENT | + SERVICE_ACCEPT_SESSIONCHANGE ; + } + + // Save the new status we've been given + ServiceStatus.dwCurrentState = State; + ServiceStatus.dwWin32ExitCode = Exitcode; + ServiceStatus.dwWaitHint = Timeout; + + // Update the checkpoint variable to let the SCM know that we + // haven't died if requests take a long time + if ((State == SERVICE_RUNNING) || (State == SERVICE_STOPPED)) { + ServiceStatus.dwCheckPoint = 0; + } else { + ServiceStatus.dwCheckPoint++; + } + + // Tell the SCM our new status + return SetServiceStatus(ServiceHandle, &ServiceStatus); +} + +void Ext2StopService() +{ + Ext2ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); + + if (ServiceNotify) { + UnregisterDeviceNotification(ServiceNotify); + ServiceNotify = NULL; + } + + /* issue stop event to main thread */ + Ext2StopPipeSrv(); + + Ext2ReportStatus(SERVICE_STOPPED, NO_ERROR, 0); +} + +VOID Ext2DrivesChangeNotify(BOOLEAN bArrival) +{ + return; +} + +VOID Ext2CleanupSession(DWORD sid) +{ +} + +DWORD WINAPI +Ext2CtrlService( + DWORD ctrlcode, DWORD dwEventType, + LPVOID lpEventData, LPVOID lpContext + ) +{ + switch(ctrlcode) + { + + case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: + // STOP : The service must stop + Ext2StopService(); + break; + + case SERVICE_CONTROL_INTERROGATE: + // QUERY : Service control manager just wants to know our state + break; + + case SERVICE_CONTROL_DEVICEEVENT: + { + PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpEventData; + PDEV_BROADCAST_DEVICEINTERFACE lpdbi = (PDEV_BROADCAST_DEVICEINTERFACE) lpEventData; + + if (lpdbv->dbcv_devicetype != DBT_DEVTYP_VOLUME && + lpdbi->dbcc_devicetype != DBT_DEVTYP_DEVICEINTERFACE + ) { + break; + } + + if (dwEventType == DBT_DEVICEREMOVECOMPLETE) { + Ext2DrivesChangeNotify(FALSE); + } else if (dwEventType == DBT_DEVICEARRIVAL) { + Ext2DrivesChangeNotify(TRUE); + } + + break; + } + + case SERVICE_CONTROL_POWEREVENT: + + switch (dwEventType) { + + case PBT_APMQUERYSUSPEND: + MsgLog("Power event: PBT_APMQUERYSUSPEND.\n"); + //Ext2StartFlushThread(); + // Ext2FlushVolume(ASSDDISK_VOLUME); + break; + + case PBT_APMQUERYSUSPENDFAILED: + MsgLog("Power event: APMQUERYSUSPENDFAILED.\n"); + break; + + case PBT_APMSUSPEND: + MsgLog("Power event: PBT_APMSUSPEND.\n"); + break; + + case PBT_APMRESUMESUSPEND: + MsgLog("Power event: PBT_APMRESUMESUSPEND.\n"); + Ext2DrivesChangeNotify(TRUE); + break; + + case PBT_APMQUERYSTANDBY: + MsgLog("Power event: PBT_APMQUERYSTANDBY.\n"); + break; + + case PBT_APMQUERYSTANDBYFAILED: + MsgLog("Power event: APMQUERYSTANDBYFAILED.\n"); + break; + + case PBT_APMSTANDBY: + MsgLog("Power event: PBT_APMSTANDBY.\n"); + break; + + case PBT_APMRESUMESTANDBY: + MsgLog("Power event: PBT_APMRESUMESTANDBY.\n"); + break; + + case PBT_APMRESUMECRITICAL: + MsgLog("Power event: PBT_APMRESUMECRITICAL.\n"); + break; + + case PBT_APMPOWERSTATUSCHANGE: + MsgLog("Power event: PBT_APMPOWERSTATUSCHANGE\n"); + break; + + case PBT_APMRESUMEAUTOMATIC: + MsgLog("Power event: PBT_APMRESUMEAUTOMATIC\n"); + break; + + default: + MsgLog("Power event: unknown value %u\n", dwEventType); + break; + } + break; + + + case SERVICE_CONTROL_SESSIONCHANGE: + + switch (dwEventType) { + + case WTS_CONSOLE_CONNECT: + MsgLog("Session event: Console connected.\n"); + break; + + case WTS_CONSOLE_DISCONNECT: + MsgLog("Session event: Console disconnect.\n"); + break; + + case WTS_REMOTE_CONNECT: + MsgLog("Session event: Remote connected.\n"); + break; + + case WTS_REMOTE_DISCONNECT: + MsgLog("Session event: Remote disconnect.\n"); + break; + + case WTS_SESSION_LOCK: + MsgLog("Session event: Session locked.\n"); + break; + case WTS_SESSION_UNLOCK: + MsgLog("Session event: Session unlocked.\n"); + break; + + case WTS_SESSION_LOGON: + { + PWTSSESSION_NOTIFICATION pwn = (PWTSSESSION_NOTIFICATION)lpEventData; + MsgLog("Session event: Session logon.\n"); + Ext2StartUserTask(NULL, _T("/startmgr"), pwn->dwSessionId, FALSE); + break; + } + + case WTS_SESSION_LOGOFF: + { + PWTSSESSION_NOTIFICATION pwn = (PWTSSESSION_NOTIFICATION)lpEventData; + MsgLog("Session event: Session logoff.\n"); + if (pwn && pwn->cbSize >= sizeof(WTSSESSION_NOTIFICATION)) { + Ext2CleanupSession(pwn->dwSessionId); + } + break; + } + + default: + MsgLog("Session event: unknown value: %u.\n", dwEventType); + break; + } + break; + + case SERVICE_ACCEPT_HARDWAREPROFILECHANGE: + + default: + // Control code not recognised + break; + + } + + // Tell the control manager what we're up to. + Ext2ReportStatus(ServiceStatus.dwCurrentState, NO_ERROR, 0); + + return NO_ERROR; +} + +VOID +Ext2StartMain(VOID * arg) +{ + Ext2StartPipeSrv(); + Ext2ReportStatus(SERVICE_RUNNING, NO_ERROR, 0); +} + + +#define EXT2_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +EXT2_GUID(GUID_DEVINTERFACE_DISK, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, \ + 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); + +VOID +Ext2RegisterDeviceInterface(SERVICE_STATUS_HANDLE handle, + GUID guid, HDEVNOTIFY *notify) +{ + DEV_BROADCAST_DEVICEINTERFACE bd; + + ZeroMemory (&bd, sizeof(bd)); + bd.dbcc_size = sizeof(bd); + bd.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + bd.dbcc_classguid = guid; + *notify = RegisterDeviceNotification(handle, &bd, + DEVICE_NOTIFY_SERVICE_HANDLE); +} + + +void WINAPI +Ext2ServiceEntry(DWORD argc, char**argv) +{ + // register the service control handler + ServiceHandle = RegisterServiceCtrlHandlerEx(_T("Ext2Srv"), Ext2CtrlService, NULL); + if (ServiceHandle == 0) { + return; + } + + // setup standard service state values + ServiceStatus.dwServiceType = SERVICE_WIN32; + ServiceStatus.dwServiceSpecificExitCode = 0; + + // report our status to the SCM + Ext2ReportStatus(SERVICE_START_PENDING, NO_ERROR, 600); + + Ext2RegisterDeviceInterface(ServiceHandle, GUID_DEVINTERFACE_DISK, + &ServiceNotify); + + // Now start the service for real + Ext2StartMain(NULL); + return; +} + + +VOID +Ext2StartService(VOID *arg) +{ + SERVICE_TABLE_ENTRY Ext2SeriveTable[] = + { + {_T("Ext2Srv"), (LPSERVICE_MAIN_FUNCTION)Ext2ServiceEntry}, + {NULL, NULL} + }; + + // let service control dispatcher start Ext2Mgr + StartServiceCtrlDispatcher(Ext2SeriveTable); +} + +#define SERVICE_CMD_LENGTH MAX_PATH + +int +Ext2SetupService(BOOL bInstall) +{ + TCHAR Target[SERVICE_CMD_LENGTH]; + SC_HANDLE hService; + SC_HANDLE hManager; + + // get the filename of this executable + if (GetModuleFileName(NULL, Target, SERVICE_CMD_LENGTH - 20) == 0) { + MessageBox(NULL, _T("Ext2Srv: Unable to install as service"), NULL, + MB_OK | MB_ICONERROR); + return FALSE; + } + + // open Service Control Manager + hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hManager == NULL) { + MessageBox(NULL, _T("Ext2Srv: cannot open Service Control Manager"), + NULL, MB_OK | MB_ICONERROR); + return FALSE; + } + + if (bInstall) { + + // now create service entry for Ext2Mgr + hService = CreateService( + hManager, // SCManager database + _T("Ext2Srv"), // name of service + _T("Ext2Fsd Service Manager"), // name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS | // service type + SERVICE_INTERACTIVE_PROCESS, + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + Target, // service's binary + NULL, // no load ordering group + NULL, // no tag identifier + NULL, // dependencies + NULL, // LocalSystem account + NULL); // no password + + if (hService == NULL) { + + DWORD error = GetLastError(); + if (error == ERROR_SERVICE_EXISTS) { + MessageBox(NULL, _T("Ext2Srv is already registered."), NULL, + MB_OK | MB_ICONERROR); + } else { + MessageBox(NULL, _T("Ext2Srv couldn't be registered."), NULL, + MB_OK | MB_ICONERROR); + } + } else { + + CloseServiceHandle(hService); + + // got Ext2Mgr installed as a service + MessageBox(NULL, _T("Ext2Srv service was successfully registered. \n\n" + "You can modify the default settings and start/stop it from Control Panel.\n" + "The service will automatically run the next time when system is restarted.\n"), + NULL, MB_OK | MB_ICONINFORMATION); + } + + } else { + + /* open the service of Pipe Event Engine */ + hService = OpenService(hManager, _T("Ext2Srv"), SERVICE_ALL_ACCESS); + + if (hService != NULL) { + + SERVICE_STATUS status; + + // stop the service + if (ControlService(hService, SERVICE_CONTROL_STOP, &status)) { + + while(QueryServiceStatus(hService, &status)) { + if (status.dwCurrentState == SERVICE_STOP_PENDING) { + Sleep(1000); + } else { + break; + } + } + + if (status.dwCurrentState != SERVICE_STOPPED) { + MessageBox(NULL, _T("Ext2Srv: service couldn't be stopped !"), + NULL, MB_OK | MB_ICONERROR); + } + } + + // remove the service from the SCM + if (DeleteService(hService)) { + MessageBox(NULL, _T("Ext2Srv: service has been unregistered."), + NULL, MB_OK | MB_ICONINFORMATION); + } else { + DWORD error = GetLastError(); + if (error == ERROR_SERVICE_MARKED_FOR_DELETE) { + MessageBox(NULL, _T("Ext2Srv: service is already unregistered"), + NULL, MB_OK | MB_ICONEXCLAMATION); + } else { + MessageBox(NULL, _T("Ext2Srv: service could not be unregistered"), + NULL, MB_OK | MB_ICONERROR); + } + } + + CloseServiceHandle(hService); + } + } + + CloseServiceHandle(hManager); + + return TRUE; +} + + +/* + * parameter process engine + */ + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int getopt(int argc, char * const argv[], const char *optstring) +{ + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || *place == 0) { /* update scanning pointer */ + optreset = 0; + place = argv[optind]; + if (optind >= argc || *place++ != '-') { + /* Argument is absent or is not an option */ + place = EMSG; + return (-1); + } + optopt = *place++; + if (optopt == '-' && *place == 0) { + /* "--" => end of options */ + ++optind; + place = EMSG; + return (-1); + } + if (optopt == 0) { + /* Solitary '-', treat as a '-' option + if the program (eg su) is looking for it. */ + place = EMSG; + if (strchr(optstring, '-') == NULL) + return -1; + optopt = '-'; + } + } else + optopt = *place++; + + /* See if option letter is one the caller wanted */ + if (optopt == ':' || (oli = strchr((char *)optstring, optopt)) == NULL) { + if (*place == 0) + ++optind; + if (opterr && *optstring != ':') + (void)fprintf(stderr, "unknown option -- %c\n", optopt); + return (BADCH); + } + + /* Does this option need an argument? */ + if (oli[1] != ':') { + /* don't need argument */ + optarg = NULL; + if (*place == 0) + ++optind; + } else { + /* Option-argument is either the rest of this argument or the + entire next argument. */ + if (*place) + optarg = place; + else if (argc > ++optind) + optarg = argv[optind]; + else { + /* option-argument absent */ + place = EMSG; + if (*optstring == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr,"option requires an argument - %c\n", optopt); + return (BADCH); + } + place = EMSG; + ++optind; + } + return (optopt); /* return option letter */ +} + + +void Ext2Log(DWORD ll, char *fn, int ln, char *format, ... ) +{ + va_list ap = NULL; + SYSTEMTIME st = {0}; + DWORD w = 0; + int i = 0; + CHAR s[260] = {0}; + + if (ll == EXT2_LOG_DUMP) { + /* do nothing for MsgDump */ + } else { + GetLocalTime(&st); + sprintf_s(s, 256, "%2.2u:%2.2u:%2.2u (%x): ", st.wHour, + st.wMinute, st.wSecond, GetCurrentThreadId()); + i = (int)strlen(s); + } + + /* write user message to buffer s */ + va_start(ap, format); + _vsnprintf(&s[i], 259 - i, format, ap); + va_end(ap); + + printf("%s", s); +} + + +INT __cdecl _tmain(INT argc, TCHAR *argv[]) +{ + DWORD rc = 0; + BOOL console = FALSE; + + if (argc >= 2) { + + if (0 == _tcsicmp(argv[1], _T("/installasservice"))) { + return Ext2SetupService(TRUE); + } + + if (0 == _tcsicmp(argv[1], _T("/removeservice"))) { + return Ext2SetupService(FALSE); + } + + if (0 == _tcsicmp(argv[1], _T("/startmgr"))) { + return Ext2StartMgrAsUser(); + } + + if (argc >= 4) { + + if (0 == _tcsicmp(argv[1], _T("/mount"))) { + Ext2AssignDrvLetter(argv[3], argv[2][0]); + return 0; + } + + } else if (argc >= 3) { + + if (0 == _tcsicmp(argv[1], _T("/umount"))) { + Ext2RemoveDrvLetter(argv[2][0]); + return 0; + } + + if (0 == _tcsicmp(argv[1], _T("/add"))) { + Ext2DrvNotify(argv[2][0], TRUE); + Sleep(1000); + Ext2DrvNotify(argv[2][0], TRUE); + return 0; + } + + if (0 == _tcsicmp(argv[1], _T("/del"))) { + Ext2DrvNotify(argv[2][0], FALSE); + Sleep(1000); + Ext2DrvNotify(argv[2][0], FALSE); + return 0; + } + } + } + + /* enable SE_TCB_NAME privilege */ + Ext2EnablePrivilege(SE_TCB_NAME); + + + /* service mode */ + Ext2StartService(NULL); + + return 0; } \ No newline at end of file diff --git a/Ext2Srv/Ext2Srv.h b/Ext2Srv/Ext2Srv.h index 3ecf04c..f273dc1 100644 --- a/Ext2Srv/Ext2Srv.h +++ b/Ext2Srv/Ext2Srv.h @@ -1,128 +1,128 @@ -#ifndef _EXT2_SRV_INCLUDE_ -#define _EXT2_SRV_INCLUDE_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * global defintions - */ - -#define CL_ASSERT(cond) do {switch('x') {case (cond): case 0: break;}} while (0) - -#define DEBUG(...) do {} while(0) - -/* - * resources - */ - -#define IDI_MAINFRAME 101 - -/* - * global defintions - */ - -#ifdef _DEBUG - -#define EXT2_BREAK() DebugBreak() -#define EXT2_ASSERT(X) _ASSERT(X) - -#else - -#define EXT2_BREAK() do {} while(0) -#define EXT2_ASSERT(X) do {} while(0) -#endif - -/* - * log filter level - */ - - -#define EXT2_LOG_CONSOLE (0x80000000) /* print to screen */ -#define EXT2_LOG_ERROR (0x00000001) /* critical messagre */ -#define EXT2_LOG_MESSAGE (0x00000002) /* information */ - -#define EXT2_LOG_DUMP (0x40000002) /* dump and message*/ - - -void Ext2Log(DWORD ll, char *fn, int ln, char *format, ... ); - -/* - * message / error log - */ -#define MsgDump(F, ...) \ - do { \ - Ext2Log(EXT2_LOG_DUMP, __FUNCTION__, __LINE__, \ - ##F, ##__VA_ARGS__); \ - } while(0) - -#define MsgLog(F, ...) \ - do { \ - Ext2Log(EXT2_LOG_MESSAGE, __FUNCTION__, __LINE__, \ - ##F, ##__VA_ARGS__); \ - } while(0) - - -#define ErrLog(F, ...) \ - do { \ - Ext2Log(EXT2_LOG_ERROR, __FUNCTION__, __LINE__, \ - ##F, ##__VA_ARGS__); \ - } while(0) - - - -/* - * structure definitions - */ - - -typedef struct _EXT2_PIPE { - struct _EXT2_PIPE *l; /* next pipe handle */ - HANDLE p; /* pipe handle */ - HANDLE e; /* event handle */ - HANDLE q; /* quiting */ - OVERLAPPED o; /* overlap info */ - volatile BOOL s; /* stop flag */ -} EXT2_PIPE, *PEXT2_PIPE; - - -/* - * Ext2Pipe.cpp - */ - - -DWORD Ext2StartPipeSrv(); -VOID Ext2StopPipeSrv(); - -INT Ext2NotifyUser(TCHAR *task, ULONG pid); - -/* - * Mount.cpp (native API) - */ - -BOOL Ext2EnablePrivilege(LPCTSTR lpszPrivilegeName); - -VOID -Ext2DrvNotify(TCHAR drive, int add); - -BOOL Ext2AssignDrvLetter(TCHAR *dev, TCHAR drv); -BOOL Ext2RemoveDrvLetter(TCHAR drive); - -int Ext2StartUserTask(TCHAR *usr, TCHAR *srv, DWORD sid, BOOL); -INT Ext2StartMgrAsUser(); - -/* - * Ext2Srv.cpp - */ - -VOID Ext2DrivesChangeNotify(BOOLEAN bArrival); - -#endif /* _EXT2_SRV_INCLUDE_ */ +#ifndef _EXT2_SRV_INCLUDE_ +#define _EXT2_SRV_INCLUDE_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * global defintions + */ + +#define CL_ASSERT(cond) do {switch('x') {case (cond): case 0: break;}} while (0) + +#define DEBUG(...) do {} while(0) + +/* + * resources + */ + +#define IDI_MAINFRAME 101 + +/* + * global defintions + */ + +#ifdef _DEBUG + +#define EXT2_BREAK() DebugBreak() +#define EXT2_ASSERT(X) _ASSERT(X) + +#else + +#define EXT2_BREAK() do {} while(0) +#define EXT2_ASSERT(X) do {} while(0) +#endif + +/* + * log filter level + */ + + +#define EXT2_LOG_CONSOLE (0x80000000) /* print to screen */ +#define EXT2_LOG_ERROR (0x00000001) /* critical messagre */ +#define EXT2_LOG_MESSAGE (0x00000002) /* information */ + +#define EXT2_LOG_DUMP (0x40000002) /* dump and message*/ + + +void Ext2Log(DWORD ll, char *fn, int ln, char *format, ... ); + +/* + * message / error log + */ +#define MsgDump(F, ...) \ + do { \ + Ext2Log(EXT2_LOG_DUMP, __FUNCTION__, __LINE__, \ + ##F, ##__VA_ARGS__); \ + } while(0) + +#define MsgLog(F, ...) \ + do { \ + Ext2Log(EXT2_LOG_MESSAGE, __FUNCTION__, __LINE__, \ + ##F, ##__VA_ARGS__); \ + } while(0) + + +#define ErrLog(F, ...) \ + do { \ + Ext2Log(EXT2_LOG_ERROR, __FUNCTION__, __LINE__, \ + ##F, ##__VA_ARGS__); \ + } while(0) + + + +/* + * structure definitions + */ + + +typedef struct _EXT2_PIPE { + struct _EXT2_PIPE *l; /* next pipe handle */ + HANDLE p; /* pipe handle */ + HANDLE e; /* event handle */ + HANDLE q; /* quiting */ + OVERLAPPED o; /* overlap info */ + volatile BOOL s; /* stop flag */ +} EXT2_PIPE, *PEXT2_PIPE; + + +/* + * Ext2Pipe.cpp + */ + + +DWORD Ext2StartPipeSrv(); +VOID Ext2StopPipeSrv(); + +INT Ext2NotifyUser(TCHAR *task, ULONG pid); + +/* + * Mount.cpp (native API) + */ + +BOOL Ext2EnablePrivilege(LPCTSTR lpszPrivilegeName); + +VOID +Ext2DrvNotify(TCHAR drive, int add); + +BOOL Ext2AssignDrvLetter(TCHAR *dev, TCHAR drv); +BOOL Ext2RemoveDrvLetter(TCHAR drive); + +int Ext2StartUserTask(TCHAR *usr, TCHAR *srv, DWORD sid, BOOL); +INT Ext2StartMgrAsUser(); + +/* + * Ext2Srv.cpp + */ + +VOID Ext2DrivesChangeNotify(BOOLEAN bArrival); + +#endif /* _EXT2_SRV_INCLUDE_ */ diff --git a/Ext2Srv/Ext2Srv.rc b/Ext2Srv/Ext2Srv.rc index f9940fa..0eb9e2e 100644 --- a/Ext2Srv/Ext2Srv.rc +++ b/Ext2Srv/Ext2Srv.rc @@ -1,125 +1,125 @@ -// Microsoft Visual C++ generated resource script. -// -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Chinese (P.R.C.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) -#ifdef _WIN32 -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED -#pragma code_page(936) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -1 TEXTINCLUDE -BEGIN -END - -#endif // APSTUDIO_INVOKED - -#endif // Chinese (P.R.C.) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,7,9 - PRODUCTVERSION 1,4,7,9 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x9L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Matt Wu " - VALUE "CompanyName", "www.ext2fsd.com" - VALUE "FileDescription", "Ext2Fsd Service Management" - VALUE "FileVersion", "1.4.7.9" - VALUE "InternalName", "Ext2Srv.exe" - VALUE "LegalCopyright", "Matt Wu " - VALUE "OriginalFilename", "Ext2Srv.exe" - VALUE "ProductName", "Ext2Fsd Service" - VALUE "ProductVersion", "1.4.7.9" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_MAINFRAME ICON "./Ext2Srv.ico" -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +// Microsoft Visual C++ generated resource script. +// +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Chinese (P.R.C.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +#ifdef _WIN32 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +1 TEXTINCLUDE +BEGIN +END + +#endif // APSTUDIO_INVOKED + +#endif // Chinese (P.R.C.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,4,7,9 + PRODUCTVERSION 1,4,7,9 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x9L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Matt Wu " + VALUE "CompanyName", "www.ext2fsd.com" + VALUE "FileDescription", "Ext2Fsd Service Management" + VALUE "FileVersion", "1.4.7.9" + VALUE "InternalName", "Ext2Srv.exe" + VALUE "LegalCopyright", "Matt Wu " + VALUE "OriginalFilename", "Ext2Srv.exe" + VALUE "ProductName", "Ext2Fsd Service" + VALUE "ProductVersion", "1.4.7.9" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MAINFRAME ICON "./Ext2Srv.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Ext2Srv/MAKEFILE b/Ext2Srv/MAKEFILE index ef95367..ac47d2b 100644 --- a/Ext2Srv/MAKEFILE +++ b/Ext2Srv/MAKEFILE @@ -1,11 +1,11 @@ -BUILD_ALLOW_COMPILER_WARNINGS=1 -BUILD_ALLOW_LINKER_WARNINGS=1 - -# -# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source -# file to this component. This file merely indirects to the real make file -# that is shared by all the driver components of the Windows NT DDK -# - -!INCLUDE $(NTMAKEENV)\makefile.def - +BUILD_ALLOW_COMPILER_WARNINGS=1 +BUILD_ALLOW_LINKER_WARNINGS=1 + +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def + diff --git a/Ext2Srv/Mount.cpp b/Ext2Srv/Mount.cpp index a720fb6..4105637 100644 --- a/Ext2Srv/Mount.cpp +++ b/Ext2Srv/Mount.cpp @@ -1,466 +1,466 @@ -#include -#include -#include - - -BOOL Ext2SetPrivilege(HANDLE token, LPCTSTR lpszPrivilegeName) -{ - TOKEN_PRIVILEGES tp = {0}; - LUID luid; - DWORD le; - BOOL rc; - - rc = LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid); - if(!rc) - goto errorout; - - /* initialize token privilege */ - tp.PrivilegeCount = 1; - tp.Privileges[0].Luid = luid; - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - rc = AdjustTokenPrivileges(token, FALSE, &tp, NULL, NULL, NULL); - if (!rc) - le = GetLastError(); - -errorout: - - return rc; -} - - -BOOL Ext2EnablePrivilege(LPCTSTR lpszPrivilegeName) -{ - HANDLE token; - BOOL rc; - - rc = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | - TOKEN_QUERY | TOKEN_READ, &token); - if(!rc) - goto errorout; - - rc = Ext2SetPrivilege(token, lpszPrivilegeName); - CloseHandle(token); - -errorout: - - return rc; -} - -VOID -Ext2DrvNotify(TCHAR drive, int add) -{ - DEV_BROADCAST_VOLUME dbv; - DWORD target = BSM_APPLICATIONS; - unsigned long drv = 0; - - if (drive >= 'A' && drive <= 'Z') - drv = drive - 'A'; - else if(drive >= 'a' && drive <= 'z') - drv = drive - 'a'; - else - return; - - dbv.dbcv_size = sizeof( dbv ); - dbv.dbcv_devicetype = DBT_DEVTYP_VOLUME; - dbv.dbcv_reserved = 0; - dbv.dbcv_unitmask = (1 << drv); - dbv.dbcv_flags = DBTF_NET; - BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_FORCEIFHUNG | - BSF_NOHANG | BSF_NOTIMEOUTIFNOTHUNG, - &target, WM_DEVICECHANGE, add ? - DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, - (LPARAM)(DEV_BROADCAST_HDR *)&dbv ); -} - - -DWORD Ext2QueryMgr(TCHAR *Auth, DWORD *pids, DWORD as) -{ - DWORD total = 0; - HANDLE p = NULL; - PROCESSENTRY32 r = {0}; - - p = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (INVALID_HANDLE_VALUE == p) - return 0; - - r.dwSize=sizeof(PROCESSENTRY32); - if (!Process32First(p, &r)) { - goto errorout; - } - - do { - TCHAR *n = _tcsrchr(&r.szExeFile[0], _T('\\')); - if (!n) - n = &r.szExeFile[0]; - if (_tcsicmp(n, Auth) == 0) { - pids[total++] = r.th32ProcessID; - if (total >= as) - break; - } - - } while(Process32Next(p, &r)); - -errorout: - - CloseHandle(p); - - return total; -} - -TCHAR * Ext2BuildSrvCMD(TCHAR *task) -{ - TCHAR cmd[258]= {0}, *p, *refresh = NULL; - int len = 0; - - if (GetModuleFileName(NULL, cmd, 256)) { - } else { - _tcscpy(cmd, GetCommandLine()); - p = _tcsstr(cmd, _T("/")); - if (p) - *p = 0; - } - - len = (int)_tcslen(cmd) + 40; - refresh = new TCHAR[len]; - if (!refresh) - goto errorout; - memset(refresh, 0, sizeof(TCHAR)*len); - _tcscpy_s(refresh, len - 1, cmd); - _tcscat_s(refresh, len, _T(" ")); - _tcscat_s(refresh, len, task); - -errorout: - return refresh; -} - -TCHAR * -Ext2StrStr(TCHAR *s, TCHAR *t) -{ - int ls = (int)_tcslen(s), lt = (int)_tcslen(t), i; - for (i = 0; i + lt <= ls; i++) { - if (0 == _tcsnicmp(&s[i], t, lt)) - return &s[i]; - } - - return NULL; -} - -TCHAR * Ext2BuildUsrCMD(TCHAR *task) -{ - TCHAR cmd[258]= {0}, *p, *refresh = NULL; - int len = 0; - - if (GetModuleFileName(NULL, cmd, 256)) { - } else { - _tcscpy(cmd, GetCommandLine()); - } - - p = Ext2StrStr(cmd, _T("Ext2Srv")); - if (p) - *p = 0; - - len = (int)_tcslen(cmd) + 10 + (int)_tcslen(task); - refresh = new TCHAR[len]; - if (!refresh) - goto errorout; - memset(refresh, 0, sizeof(TCHAR)*len); - _tcscpy_s(refresh, len - 1, cmd); - _tcscat_s(refresh, len, task); - -errorout: - return refresh; -} - -int Ext2AdjustTokenGroups(HANDLE token, LPCTSTR group) -{ - TOKEN_GROUPS tg = {0}; - PSID sid = NULL; - DWORD le; - BOOL rc; - - - rc = ConvertStringSidToSid(group, &sid); - if(!rc) - goto errorout; - - /* initialize token groups */ - tg.GroupCount = 1; - tg.Groups[0].Sid = sid; - tg.Groups[0].Attributes = SE_GROUP_OWNER; - rc = AdjustTokenGroups(token, FALSE, &tg, sizeof(tg), NULL, NULL); - if (!rc) - le = GetLastError(); - -errorout: - - return rc; -} - -int Ext2CreateUserToken(DWORD sid, HANDLE *token, BOOL bElevated) -{ - HANDLE token_user = NULL; - int rc = -1; - - if (!token) - goto errorout; - - rc = WTSQueryUserToken(sid, &token_user); - if (!rc) { - rc = -1 * GetLastError(); - goto errorout; - } - - rc = DuplicateTokenEx(token_user, MAXIMUM_ALLOWED, NULL, - SecurityIdentification, TokenPrimary, - token); - if (!rc) { - rc = -1 * GetLastError(); - goto errorout; - } - - if (bElevated) { - Ext2SetPrivilege(token, SE_IMPERSONATE_NAME); - Ext2SetPrivilege(token, SE_CHANGE_NOTIFY_NAME); - Ext2SetPrivilege(token, SE_CREATE_GLOBAL_NAME); - - Ext2AdjustTokenGroups(token, _T("S-1-5-32-544")); - } -errorout: - - if (token_user && token_user != INVALID_HANDLE_VALUE) - CloseHandle(token_user); - - return rc; -} - - -int Ext2StartUserTask(TCHAR *usr, TCHAR *srv, DWORD sid, BOOL bElevated) -{ - LPTSTR cmd = NULL; - STARTUPINFO si = {0}; - PROCESS_INFORMATION pi = {0}; - HANDLE token = 0; - int rc = -1; - - if (usr) - cmd = Ext2BuildUsrCMD(usr); - else - cmd = Ext2BuildSrvCMD(srv); - if (!cmd) { - rc = -1; - goto errorout; - } - - rc = Ext2CreateUserToken(sid, &token, bElevated); - if (!rc) { - rc = -1 * GetLastError(); - goto errorout; - } - - si.cb = sizeof( STARTUPINFO ); - rc = CreateProcessAsUser(token, NULL, cmd, NULL, NULL, - FALSE, NORMAL_PRIORITY_CLASS | - CREATE_NO_WINDOW, NULL, NULL, - &si, &pi ); - if (!rc) { - rc = -1 * GetLastError(); - goto errorout; - } - - if (!GetExitCodeProcess(pi.hProcess, (LPDWORD)&rc)) { - rc = -2; - } - - if (pi.hProcess != INVALID_HANDLE_VALUE) { - CloseHandle(pi.hProcess); - } - if (pi.hThread != INVALID_HANDLE_VALUE) { - CloseHandle(pi.hThread); - } - -errorout: - - if (cmd) - delete []cmd; - - if (token) - CloseHandle(token); - - return rc; -} - -INT Ext2NotifyUser(TCHAR *task, ULONG mgr) -{ - DWORD pid[64] = {0}, n, i, sid = 0; - INT rc = -1; - - n = Ext2QueryMgr(_T("Ext2Mgr.exe"), pid, 63); - if (mgr) - pid[n++] = mgr; - - for (i = 0; i < n && pid[i]; i++) { - - rc = ProcessIdToSessionId(pid[i], &sid); - if (!rc) { - continue; - } - - if (!mgr && mgr == pid[i]) { - n--; - rc = Ext2StartUserTask(0, task, sid, FALSE); - } else { - Ext2StartUserTask(0, task, sid, FALSE); - } - } - - return rc; -} - - -BOOL Ext2AssignDrvLetter(TCHAR *dev, TCHAR drv) -{ - TCHAR dos[8]; - - _stprintf_s(dos, 8, _T("%C:"), drv); - if (!DefineDosDevice(DDD_RAW_TARGET_PATH, dos, dev)) { - ErrLog("mount: failed to assigned drive letter %C:.\n", drv); - return 0; - } - - Ext2DrvNotify(drv, TRUE); - - return TRUE; -} - -BOOL Ext2RemoveDrvLetter(TCHAR drive) -{ - TCHAR dosDev[MAX_PATH]; - - /* remove drive letter */ - _stprintf_s(dosDev, MAX_PATH, _T("%C:"), drive); - DefineDosDevice(DDD_REMOVE_DEFINITION, - dosDev, NULL); - Ext2DrvNotify(drive, FALSE); - - return TRUE; -} - -CHAR *Ext2QueryAutoUserList() -{ - int rc = TRUE; - HKEY hKey; - CHAR keyPath[MAX_PATH]; - CHAR *userList = NULL; - LONG status, type, len; - - /* Open ext2fsd sevice key */ - strcpy (keyPath, "SYSTEM\\CurrentControlSet\\Services\\Ext2Fsd\\Parameters") ; - status = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE, - keyPath, - 0, - KEY_READ | KEY_WOW64_64KEY, - &hKey) ; - if (status != ERROR_SUCCESS) { - rc = FALSE; - goto errorout; - } - - /* query autorun user list */ - len = MAX_PATH - 1; - userList = new CHAR[len + 1]; - if (!userList) - goto errorout; - memset(userList, 0, len + 1); - status = RegQueryValueEx( hKey, - "AutorunUsers", - 0, - (LPDWORD)&type, - (BYTE *)userList, - (LPDWORD)&len); - -errorout: - - RegCloseKey(hKey); - - return userList; -} - - -BOOL Ext2RunMgrForCurrentUserVista() -{ - CHAR *userList = NULL, *user, e; - CHAR userName[MAX_PATH] = {0}; - DWORD userLen = MAX_PATH - 1; - BOOL rc = FALSE; - - if (!GetUserName(userName, &userLen)) - return FALSE; - - userList = Ext2QueryAutoUserList(); - if (!userList) - return FALSE; - - user = userList; - while (user = Ext2StrStr(user, userName)) { - if (user > userList) { - e = user[-1]; - if (e != ',' && e != ';') { - user = user + strlen(userName); - continue; - } - } - e = user[strlen(userName)]; - if (!e || e == ',' || e == ';') { - rc = TRUE; - goto errorout; - } - user = user + strlen(userName); - } - -errorout: - - if (userList) - delete [] userList; - - return rc; -} - -INT Ext2StartMgrAsUser() -{ - SHELLEXECUTEINFO sei = {0}; - TCHAR cmd[258] = {0}, *t; - DWORD rc = 0; - - if (!Ext2RunMgrForCurrentUserVista()) { - return 0; - } - - /* sleeping 1 second before proceeding */ - Sleep(1000); - - /* building task CMD path */ - rc = GetModuleFileName(NULL, cmd, 256); - if (!rc) { - return 0; - } - - t = Ext2StrStr(cmd, "Ext2Srv.exe"); - if (!t) { - return 0; - } - t[4] = _T('M'); - t[5] = _T('g'); - t[6] = _T('r'); - - /* starting Ext2Mgr as elevated */ - sei.cbSize = sizeof(SHELLEXECUTEINFO); - sei.fMask = SEE_MASK_FLAG_DDEWAIT | - SEE_MASK_NOCLOSEPROCESS; - sei.hwnd = NULL; - sei.lpFile = cmd; - sei.lpParameters = _T("/quiet"); - sei.lpVerb = _T("runas"); - sei.nShow = SW_SHOW; - - return ShellExecuteEx(&sei); -} +#include +#include +#include + + +BOOL Ext2SetPrivilege(HANDLE token, LPCTSTR lpszPrivilegeName) +{ + TOKEN_PRIVILEGES tp = {0}; + LUID luid; + DWORD le; + BOOL rc; + + rc = LookupPrivilegeValue(NULL, lpszPrivilegeName, &luid); + if(!rc) + goto errorout; + + /* initialize token privilege */ + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + rc = AdjustTokenPrivileges(token, FALSE, &tp, NULL, NULL, NULL); + if (!rc) + le = GetLastError(); + +errorout: + + return rc; +} + + +BOOL Ext2EnablePrivilege(LPCTSTR lpszPrivilegeName) +{ + HANDLE token; + BOOL rc; + + rc = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | + TOKEN_QUERY | TOKEN_READ, &token); + if(!rc) + goto errorout; + + rc = Ext2SetPrivilege(token, lpszPrivilegeName); + CloseHandle(token); + +errorout: + + return rc; +} + +VOID +Ext2DrvNotify(TCHAR drive, int add) +{ + DEV_BROADCAST_VOLUME dbv; + DWORD target = BSM_APPLICATIONS; + unsigned long drv = 0; + + if (drive >= 'A' && drive <= 'Z') + drv = drive - 'A'; + else if(drive >= 'a' && drive <= 'z') + drv = drive - 'a'; + else + return; + + dbv.dbcv_size = sizeof( dbv ); + dbv.dbcv_devicetype = DBT_DEVTYP_VOLUME; + dbv.dbcv_reserved = 0; + dbv.dbcv_unitmask = (1 << drv); + dbv.dbcv_flags = DBTF_NET; + BroadcastSystemMessage(BSF_IGNORECURRENTTASK | BSF_FORCEIFHUNG | + BSF_NOHANG | BSF_NOTIMEOUTIFNOTHUNG, + &target, WM_DEVICECHANGE, add ? + DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, + (LPARAM)(DEV_BROADCAST_HDR *)&dbv ); +} + + +DWORD Ext2QueryMgr(TCHAR *Auth, DWORD *pids, DWORD as) +{ + DWORD total = 0; + HANDLE p = NULL; + PROCESSENTRY32 r = {0}; + + p = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (INVALID_HANDLE_VALUE == p) + return 0; + + r.dwSize=sizeof(PROCESSENTRY32); + if (!Process32First(p, &r)) { + goto errorout; + } + + do { + TCHAR *n = _tcsrchr(&r.szExeFile[0], _T('\\')); + if (!n) + n = &r.szExeFile[0]; + if (_tcsicmp(n, Auth) == 0) { + pids[total++] = r.th32ProcessID; + if (total >= as) + break; + } + + } while(Process32Next(p, &r)); + +errorout: + + CloseHandle(p); + + return total; +} + +TCHAR * Ext2BuildSrvCMD(TCHAR *task) +{ + TCHAR cmd[258]= {0}, *p, *refresh = NULL; + int len = 0; + + if (GetModuleFileName(NULL, cmd, 256)) { + } else { + _tcscpy(cmd, GetCommandLine()); + p = _tcsstr(cmd, _T("/")); + if (p) + *p = 0; + } + + len = (int)_tcslen(cmd) + 40; + refresh = new TCHAR[len]; + if (!refresh) + goto errorout; + memset(refresh, 0, sizeof(TCHAR)*len); + _tcscpy_s(refresh, len - 1, cmd); + _tcscat_s(refresh, len, _T(" ")); + _tcscat_s(refresh, len, task); + +errorout: + return refresh; +} + +TCHAR * +Ext2StrStr(TCHAR *s, TCHAR *t) +{ + int ls = (int)_tcslen(s), lt = (int)_tcslen(t), i; + for (i = 0; i + lt <= ls; i++) { + if (0 == _tcsnicmp(&s[i], t, lt)) + return &s[i]; + } + + return NULL; +} + +TCHAR * Ext2BuildUsrCMD(TCHAR *task) +{ + TCHAR cmd[258]= {0}, *p, *refresh = NULL; + int len = 0; + + if (GetModuleFileName(NULL, cmd, 256)) { + } else { + _tcscpy(cmd, GetCommandLine()); + } + + p = Ext2StrStr(cmd, _T("Ext2Srv")); + if (p) + *p = 0; + + len = (int)_tcslen(cmd) + 10 + (int)_tcslen(task); + refresh = new TCHAR[len]; + if (!refresh) + goto errorout; + memset(refresh, 0, sizeof(TCHAR)*len); + _tcscpy_s(refresh, len - 1, cmd); + _tcscat_s(refresh, len, task); + +errorout: + return refresh; +} + +int Ext2AdjustTokenGroups(HANDLE token, LPCTSTR group) +{ + TOKEN_GROUPS tg = {0}; + PSID sid = NULL; + DWORD le; + BOOL rc; + + + rc = ConvertStringSidToSid(group, &sid); + if(!rc) + goto errorout; + + /* initialize token groups */ + tg.GroupCount = 1; + tg.Groups[0].Sid = sid; + tg.Groups[0].Attributes = SE_GROUP_OWNER; + rc = AdjustTokenGroups(token, FALSE, &tg, sizeof(tg), NULL, NULL); + if (!rc) + le = GetLastError(); + +errorout: + + return rc; +} + +int Ext2CreateUserToken(DWORD sid, HANDLE *token, BOOL bElevated) +{ + HANDLE token_user = NULL; + int rc = -1; + + if (!token) + goto errorout; + + rc = WTSQueryUserToken(sid, &token_user); + if (!rc) { + rc = -1 * GetLastError(); + goto errorout; + } + + rc = DuplicateTokenEx(token_user, MAXIMUM_ALLOWED, NULL, + SecurityIdentification, TokenPrimary, + token); + if (!rc) { + rc = -1 * GetLastError(); + goto errorout; + } + + if (bElevated) { + Ext2SetPrivilege(token, SE_IMPERSONATE_NAME); + Ext2SetPrivilege(token, SE_CHANGE_NOTIFY_NAME); + Ext2SetPrivilege(token, SE_CREATE_GLOBAL_NAME); + + Ext2AdjustTokenGroups(token, _T("S-1-5-32-544")); + } +errorout: + + if (token_user && token_user != INVALID_HANDLE_VALUE) + CloseHandle(token_user); + + return rc; +} + + +int Ext2StartUserTask(TCHAR *usr, TCHAR *srv, DWORD sid, BOOL bElevated) +{ + LPTSTR cmd = NULL; + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi = {0}; + HANDLE token = 0; + int rc = -1; + + if (usr) + cmd = Ext2BuildUsrCMD(usr); + else + cmd = Ext2BuildSrvCMD(srv); + if (!cmd) { + rc = -1; + goto errorout; + } + + rc = Ext2CreateUserToken(sid, &token, bElevated); + if (!rc) { + rc = -1 * GetLastError(); + goto errorout; + } + + si.cb = sizeof( STARTUPINFO ); + rc = CreateProcessAsUser(token, NULL, cmd, NULL, NULL, + FALSE, NORMAL_PRIORITY_CLASS | + CREATE_NO_WINDOW, NULL, NULL, + &si, &pi ); + if (!rc) { + rc = -1 * GetLastError(); + goto errorout; + } + + if (!GetExitCodeProcess(pi.hProcess, (LPDWORD)&rc)) { + rc = -2; + } + + if (pi.hProcess != INVALID_HANDLE_VALUE) { + CloseHandle(pi.hProcess); + } + if (pi.hThread != INVALID_HANDLE_VALUE) { + CloseHandle(pi.hThread); + } + +errorout: + + if (cmd) + delete []cmd; + + if (token) + CloseHandle(token); + + return rc; +} + +INT Ext2NotifyUser(TCHAR *task, ULONG mgr) +{ + DWORD pid[64] = {0}, n, i, sid = 0; + INT rc = -1; + + n = Ext2QueryMgr(_T("Ext2Mgr.exe"), pid, 63); + if (mgr) + pid[n++] = mgr; + + for (i = 0; i < n && pid[i]; i++) { + + rc = ProcessIdToSessionId(pid[i], &sid); + if (!rc) { + continue; + } + + if (!mgr && mgr == pid[i]) { + n--; + rc = Ext2StartUserTask(0, task, sid, FALSE); + } else { + Ext2StartUserTask(0, task, sid, FALSE); + } + } + + return rc; +} + + +BOOL Ext2AssignDrvLetter(TCHAR *dev, TCHAR drv) +{ + TCHAR dos[8]; + + _stprintf_s(dos, 8, _T("%C:"), drv); + if (!DefineDosDevice(DDD_RAW_TARGET_PATH, dos, dev)) { + ErrLog("mount: failed to assigned drive letter %C:.\n", drv); + return 0; + } + + Ext2DrvNotify(drv, TRUE); + + return TRUE; +} + +BOOL Ext2RemoveDrvLetter(TCHAR drive) +{ + TCHAR dosDev[MAX_PATH]; + + /* remove drive letter */ + _stprintf_s(dosDev, MAX_PATH, _T("%C:"), drive); + DefineDosDevice(DDD_REMOVE_DEFINITION, + dosDev, NULL); + Ext2DrvNotify(drive, FALSE); + + return TRUE; +} + +CHAR *Ext2QueryAutoUserList() +{ + int rc = TRUE; + HKEY hKey; + CHAR keyPath[MAX_PATH]; + CHAR *userList = NULL; + LONG status, type, len; + + /* Open ext2fsd sevice key */ + strcpy (keyPath, "SYSTEM\\CurrentControlSet\\Services\\Ext2Fsd\\Parameters") ; + status = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE, + keyPath, + 0, + KEY_READ | KEY_WOW64_64KEY, + &hKey) ; + if (status != ERROR_SUCCESS) { + rc = FALSE; + goto errorout; + } + + /* query autorun user list */ + len = MAX_PATH - 1; + userList = new CHAR[len + 1]; + if (!userList) + goto errorout; + memset(userList, 0, len + 1); + status = RegQueryValueEx( hKey, + "AutorunUsers", + 0, + (LPDWORD)&type, + (BYTE *)userList, + (LPDWORD)&len); + +errorout: + + RegCloseKey(hKey); + + return userList; +} + + +BOOL Ext2RunMgrForCurrentUserVista() +{ + CHAR *userList = NULL, *user, e; + CHAR userName[MAX_PATH] = {0}; + DWORD userLen = MAX_PATH - 1; + BOOL rc = FALSE; + + if (!GetUserName(userName, &userLen)) + return FALSE; + + userList = Ext2QueryAutoUserList(); + if (!userList) + return FALSE; + + user = userList; + while (user = Ext2StrStr(user, userName)) { + if (user > userList) { + e = user[-1]; + if (e != ',' && e != ';') { + user = user + strlen(userName); + continue; + } + } + e = user[strlen(userName)]; + if (!e || e == ',' || e == ';') { + rc = TRUE; + goto errorout; + } + user = user + strlen(userName); + } + +errorout: + + if (userList) + delete [] userList; + + return rc; +} + +INT Ext2StartMgrAsUser() +{ + SHELLEXECUTEINFO sei = {0}; + TCHAR cmd[258] = {0}, *t; + DWORD rc = 0; + + if (!Ext2RunMgrForCurrentUserVista()) { + return 0; + } + + /* sleeping 1 second before proceeding */ + Sleep(1000); + + /* building task CMD path */ + rc = GetModuleFileName(NULL, cmd, 256); + if (!rc) { + return 0; + } + + t = Ext2StrStr(cmd, "Ext2Srv.exe"); + if (!t) { + return 0; + } + t[4] = _T('M'); + t[5] = _T('g'); + t[6] = _T('r'); + + /* starting Ext2Mgr as elevated */ + sei.cbSize = sizeof(SHELLEXECUTEINFO); + sei.fMask = SEE_MASK_FLAG_DDEWAIT | + SEE_MASK_NOCLOSEPROCESS; + sei.hwnd = NULL; + sei.lpFile = cmd; + sei.lpParameters = _T("/quiet"); + sei.lpVerb = _T("runas"); + sei.nShow = SW_SHOW; + + return ShellExecuteEx(&sei); +} diff --git a/Ext2Srv/SOURCES b/Ext2Srv/SOURCES index 00430e1..bb10775 100644 --- a/Ext2Srv/SOURCES +++ b/Ext2Srv/SOURCES @@ -1,12 +1,12 @@ -TARGETNAME=Ext2Srv -TARGETPATH=obj -TARGETTYPE=PROGRAM -UMTYPE=windows - -INCLUDES=.;.\Libraries\;$(INCLUDES) -TARGETLIBS=$(DDK_LIB_PATH)\WtsApi32.lib \ - $(DDK_LIB_PATH)\shell32.lib -USE_MSVCRT=1 - -SOURCES=Ext2Pipe.cpp Ext2Srv.cpp \ - Mount.cpp Ext2Srv.rc +TARGETNAME=Ext2Srv +TARGETPATH=obj +TARGETTYPE=PROGRAM +UMTYPE=windows + +INCLUDES=.;.\Libraries\;$(INCLUDES) +TARGETLIBS=$(DDK_LIB_PATH)\WtsApi32.lib \ + $(DDK_LIB_PATH)\shell32.lib +USE_MSVCRT=1 + +SOURCES=Ext2Pipe.cpp Ext2Srv.cpp \ + Mount.cpp Ext2Srv.rc diff --git a/Ext2Srv/libraries/tlhelp32.h b/Ext2Srv/libraries/tlhelp32.h index e928380..10b4251 100644 --- a/Ext2Srv/libraries/tlhelp32.h +++ b/Ext2Srv/libraries/tlhelp32.h @@ -1,140 +1,140 @@ -/* - tlhelp32.h - Include file for Tool help functions. - - Written by Mumit Khan - - This file is part of a free library for the Win32 API. - - 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. - -*/ -#ifndef _TLHELP32_H -#define _TLHELP32_H -#if __GNUC__ >=3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif -#define HF32_DEFAULT 1 -#define HF32_SHARED 2 -#define LF32_FIXED 0x1 -#define LF32_FREE 0x2 -#define LF32_MOVEABLE 0x4 -#define MAX_MODULE_NAME32 255 -#define TH32CS_SNAPHEAPLIST 0x1 -#define TH32CS_SNAPPROCESS 0x2 -#define TH32CS_SNAPTHREAD 0x4 -#define TH32CS_SNAPMODULE 0x8 -#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE) -#define TH32CS_INHERIT 0x80000000 -typedef struct tagHEAPLIST32 { - DWORD dwSize; - DWORD th32ProcessID; - DWORD th32HeapID; - DWORD dwFlags; -} HEAPLIST32,*PHEAPLIST32,*LPHEAPLIST32; -typedef struct tagHEAPENTRY32 { - DWORD dwSize; - HANDLE hHandle; - DWORD dwAddress; - DWORD dwBlockSize; - DWORD dwFlags; - DWORD dwLockCount; - DWORD dwResvd; - DWORD th32ProcessID; - DWORD th32HeapID; -} HEAPENTRY32,*PHEAPENTRY32,*LPHEAPENTRY32; -typedef struct tagPROCESSENTRY32W { - DWORD dwSize; - DWORD cntUsage; - DWORD th32ProcessID; - DWORD th32DefaultHeapID; - DWORD th32ModuleID; - DWORD cntThreads; - DWORD th32ParentProcessID; - LONG pcPriClassBase; - DWORD dwFlags; - WCHAR szExeFile[MAX_PATH]; -} PROCESSENTRY32W,*PPROCESSENTRY32W,*LPPROCESSENTRY32W; -typedef struct tagPROCESSENTRY32 { - DWORD dwSize; - DWORD cntUsage; - DWORD th32ProcessID; - DWORD th32DefaultHeapID; - DWORD th32ModuleID; - DWORD cntThreads; - DWORD th32ParentProcessID; - LONG pcPriClassBase; - DWORD dwFlags; - CHAR szExeFile[MAX_PATH]; -} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32; -typedef struct tagTHREADENTRY32 { - DWORD dwSize; - DWORD cntUsage; - DWORD th32ThreadID; - DWORD th32OwnerProcessID; - LONG tpBasePri; - LONG tpDeltaPri; - DWORD dwFlags; -} THREADENTRY32,*PTHREADENTRY32,*LPTHREADENTRY32; -typedef struct tagMODULEENTRY32W { - DWORD dwSize; - DWORD th32ModuleID; - DWORD th32ProcessID; - DWORD GlblcntUsage; - DWORD ProccntUsage; - BYTE *modBaseAddr; - DWORD modBaseSize; - HMODULE hModule; - WCHAR szModule[MAX_MODULE_NAME32 + 1]; - WCHAR szExePath[MAX_PATH]; -} MODULEENTRY32W,*PMODULEENTRY32W,*LPMODULEENTRY32W; -typedef struct tagMODULEENTRY32 { - DWORD dwSize; - DWORD th32ModuleID; - DWORD th32ProcessID; - DWORD GlblcntUsage; - DWORD ProccntUsage; - BYTE *modBaseAddr; - DWORD modBaseSize; - HMODULE hModule; - char szModule[MAX_MODULE_NAME32 + 1]; - char szExePath[MAX_PATH]; -} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32; -BOOL WINAPI Heap32First(LPHEAPENTRY32,DWORD,DWORD); -BOOL WINAPI Heap32ListFirst(HANDLE,LPHEAPLIST32); -BOOL WINAPI Heap32ListNext(HANDLE,LPHEAPLIST32); -BOOL WINAPI Heap32Next(LPHEAPENTRY32); -BOOL WINAPI Module32First(HANDLE,LPMODULEENTRY32); -BOOL WINAPI Module32FirstW(HANDLE,LPMODULEENTRY32W); -BOOL WINAPI Module32Next(HANDLE,LPMODULEENTRY32); -BOOL WINAPI Module32NextW(HANDLE,LPMODULEENTRY32W); -BOOL WINAPI Process32First(HANDLE,LPPROCESSENTRY32); -BOOL WINAPI Process32FirstW(HANDLE,LPPROCESSENTRY32W); -BOOL WINAPI Process32Next(HANDLE,LPPROCESSENTRY32); -BOOL WINAPI Process32NextW(HANDLE,LPPROCESSENTRY32W); -BOOL WINAPI Thread32First(HANDLE,LPTHREADENTRY32); -BOOL WINAPI Thread32Next(HANDLE,LPTHREADENTRY32); -BOOL WINAPI Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,DWORD,LPDWORD); -HANDLE WINAPI CreateToolhelp32Snapshot(DWORD,DWORD); -#ifdef UNICODE -#define LPMODULEENTRY32 LPMODULEENTRY32W -#define LPPROCESSENTRY32 LPPROCESSENTRY32W -#define MODULEENTRY32 MODULEENTRY32W -#define Module32First Module32FirstW -#define Module32Next Module32NextW -#define PMODULEENTRY32 PMODULEENTRY32W -#define PPROCESSENTRY32 PPROCESSENTRY32W -#define PROCESSENTRY32 PROCESSENTRY32W -#define Process32First Process32FirstW -#define Process32Next Process32NextW -#endif /* UNICODE */ -#ifdef __cplusplus -} -#endif -#endif /* _TLHELP32_H */ - +/* + tlhelp32.h - Include file for Tool help functions. + + Written by Mumit Khan + + This file is part of a free library for the Win32 API. + + 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. + +*/ +#ifndef _TLHELP32_H +#define _TLHELP32_H +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#define HF32_DEFAULT 1 +#define HF32_SHARED 2 +#define LF32_FIXED 0x1 +#define LF32_FREE 0x2 +#define LF32_MOVEABLE 0x4 +#define MAX_MODULE_NAME32 255 +#define TH32CS_SNAPHEAPLIST 0x1 +#define TH32CS_SNAPPROCESS 0x2 +#define TH32CS_SNAPTHREAD 0x4 +#define TH32CS_SNAPMODULE 0x8 +#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE) +#define TH32CS_INHERIT 0x80000000 +typedef struct tagHEAPLIST32 { + DWORD dwSize; + DWORD th32ProcessID; + DWORD th32HeapID; + DWORD dwFlags; +} HEAPLIST32,*PHEAPLIST32,*LPHEAPLIST32; +typedef struct tagHEAPENTRY32 { + DWORD dwSize; + HANDLE hHandle; + DWORD dwAddress; + DWORD dwBlockSize; + DWORD dwFlags; + DWORD dwLockCount; + DWORD dwResvd; + DWORD th32ProcessID; + DWORD th32HeapID; +} HEAPENTRY32,*PHEAPENTRY32,*LPHEAPENTRY32; +typedef struct tagPROCESSENTRY32W { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; + DWORD th32DefaultHeapID; + DWORD th32ModuleID; + DWORD cntThreads; + DWORD th32ParentProcessID; + LONG pcPriClassBase; + DWORD dwFlags; + WCHAR szExeFile[MAX_PATH]; +} PROCESSENTRY32W,*PPROCESSENTRY32W,*LPPROCESSENTRY32W; +typedef struct tagPROCESSENTRY32 { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; + DWORD th32DefaultHeapID; + DWORD th32ModuleID; + DWORD cntThreads; + DWORD th32ParentProcessID; + LONG pcPriClassBase; + DWORD dwFlags; + CHAR szExeFile[MAX_PATH]; +} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32; +typedef struct tagTHREADENTRY32 { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ThreadID; + DWORD th32OwnerProcessID; + LONG tpBasePri; + LONG tpDeltaPri; + DWORD dwFlags; +} THREADENTRY32,*PTHREADENTRY32,*LPTHREADENTRY32; +typedef struct tagMODULEENTRY32W { + DWORD dwSize; + DWORD th32ModuleID; + DWORD th32ProcessID; + DWORD GlblcntUsage; + DWORD ProccntUsage; + BYTE *modBaseAddr; + DWORD modBaseSize; + HMODULE hModule; + WCHAR szModule[MAX_MODULE_NAME32 + 1]; + WCHAR szExePath[MAX_PATH]; +} MODULEENTRY32W,*PMODULEENTRY32W,*LPMODULEENTRY32W; +typedef struct tagMODULEENTRY32 { + DWORD dwSize; + DWORD th32ModuleID; + DWORD th32ProcessID; + DWORD GlblcntUsage; + DWORD ProccntUsage; + BYTE *modBaseAddr; + DWORD modBaseSize; + HMODULE hModule; + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; +} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32; +BOOL WINAPI Heap32First(LPHEAPENTRY32,DWORD,DWORD); +BOOL WINAPI Heap32ListFirst(HANDLE,LPHEAPLIST32); +BOOL WINAPI Heap32ListNext(HANDLE,LPHEAPLIST32); +BOOL WINAPI Heap32Next(LPHEAPENTRY32); +BOOL WINAPI Module32First(HANDLE,LPMODULEENTRY32); +BOOL WINAPI Module32FirstW(HANDLE,LPMODULEENTRY32W); +BOOL WINAPI Module32Next(HANDLE,LPMODULEENTRY32); +BOOL WINAPI Module32NextW(HANDLE,LPMODULEENTRY32W); +BOOL WINAPI Process32First(HANDLE,LPPROCESSENTRY32); +BOOL WINAPI Process32FirstW(HANDLE,LPPROCESSENTRY32W); +BOOL WINAPI Process32Next(HANDLE,LPPROCESSENTRY32); +BOOL WINAPI Process32NextW(HANDLE,LPPROCESSENTRY32W); +BOOL WINAPI Thread32First(HANDLE,LPTHREADENTRY32); +BOOL WINAPI Thread32Next(HANDLE,LPTHREADENTRY32); +BOOL WINAPI Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,DWORD,LPDWORD); +HANDLE WINAPI CreateToolhelp32Snapshot(DWORD,DWORD); +#ifdef UNICODE +#define LPMODULEENTRY32 LPMODULEENTRY32W +#define LPPROCESSENTRY32 LPPROCESSENTRY32W +#define MODULEENTRY32 MODULEENTRY32W +#define Module32First Module32FirstW +#define Module32Next Module32NextW +#define PMODULEENTRY32 PMODULEENTRY32W +#define PPROCESSENTRY32 PPROCESSENTRY32W +#define PROCESSENTRY32 PROCESSENTRY32W +#define Process32First Process32FirstW +#define Process32Next Process32NextW +#endif /* UNICODE */ +#ifdef __cplusplus +} +#endif +#endif /* _TLHELP32_H */ + diff --git a/Ext2Srv/libraries/wtsapi32.h b/Ext2Srv/libraries/wtsapi32.h index 5bd09bb..d4af7b3 100644 --- a/Ext2Srv/libraries/wtsapi32.h +++ b/Ext2Srv/libraries/wtsapi32.h @@ -1,177 +1,177 @@ -#ifndef _WTSAPI32_H -#define _WTSAPI32_H -#if __GNUC__ >= 3 -#pragma GCC system_header -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if (_WIN32_WINNT >= 0x0501) - // session notification message -#define WM_WTSSESSION_CHANGE 0x02B1 - -typedef enum _WTS_INFO_CLASS { - WTSInitialProgram = 0, - WTSApplicationName = 1, - WTSWorkingDirectory = 2, - WTSOEMId = 3, - WTSSessionId = 4, - WTSUserName = 5, - WTSWinStationName = 6, - WTSDomainName = 7, - WTSConnectState = 8, - WTSClientBuildNumber = 9, - WTSClientName = 10, - WTSClientDirectory = 11, - WTSClientProductId = 12, - WTSClientHardwareId = 13, - WTSClientAddress = 14, - WTSClientDisplay = 15, - WTSClientProtocolType = 16, - WTSIdleTime = 17, - WTSLogonTime = 18, - WTSIncomingBytes = 19, - WTSOutgoingBytes = 20, - WTSIncomingFrames = 21, - WTSOutgoingFrames = 22, - WTSClientInfo = 23, - WTSSessionInfo = 24 -} WTS_INFO_CLASS; - -typedef enum _WTS_CONNECTSTATE_CLASS { - WTSActive, - WTSConnected, - WTSConnectQuery, - WTSShadow, - WTSDisconnected, - WTSIdle, - WTSListen, - WTSReset, - WTSDown, - WTSInit -} WTS_CONNECTSTATE_CLASS; - - // session notification message flags -#define WTS_CONSOLE_CONNECT 0x1 -#define WTS_CONSOLE_DISCONNECT 0x2 -#define WTS_REMOTE_CONNECT 0x3 -#define WTS_REMOTE_DISCONNECT 0x4 -#define WTS_SESSION_LOGON 0x5 -#define WTS_SESSION_LOGOFF 0x6 -#define WTS_SESSION_LOCK 0x7 -#define WTS_SESSION_UNLOCK 0x8 -#define WTS_SESSION_REMOTE_CONTROL 0x9 - - // WTSRegisterSessionNotifiction flags -#define NOTIFY_FOR_THIS_SESSION 0 -#define NOTIFY_FOR_ALL_SESSIONS 1 - -BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags); -BOOL WINAPI WTSUnRegisterSessionNotification(HWND hWnd); -BOOL WINAPI WTSQueryUserToken(ULONG SessionId, PHANDLE pToken); - -#endif /* _WIN32_WINNT >= 0x0501 */ - -#if (_WIN32_WINNT >= 0x0500) - -typedef struct _WTS_SESSION_INFOW { - DWORD SessionId; - LPWSTR pWinStationName; - WTS_CONNECTSTATE_CLASS State; -} WTS_SESSION_INFOW, *PWTS_SESSION_INFOW; - -typedef struct _WTS_SESSION_INFOA { - DWORD SessionId; - LPSTR pWinStationName; - WTS_CONNECTSTATE_CLASS State; -} WTS_SESSION_INFOA, *PWTS_SESSION_INFOA; - -#ifdef UNICODE -#define WTS_SESSION_INFO WTS_SESSION_INFOW -#define PWTS_SESSION_INFO PWTS_SESSION_INFOW -#else -#define WTS_SESSION_INFO WTS_SESSION_INFOA -#define PWTS_SESSION_INFO PWTS_SESSION_INFOA -#endif - - // WTSWaitSystemEvent local server handle -#define WTS_CURRENT_SERVER_HANDLE 0 -#define WTS_CURRENT_SESSION ((DWORD)-1) - - // WTSWaitSystemEvent flags -#define WTS_EVENT_NONE 0x00000000 -#define WTS_EVENT_CREATE 0x00000001 -#define WTS_EVENT_DELETE 0x00000002 -#define WTS_EVENT_RENAME 0x00000004 -#define WTS_EVENT_CONNECT 0x00000008 -#define WTS_EVENT_DISCONNECT 0x00000010 -#define WTS_EVENT_LOGON 0x00000020 -#define WTS_EVENT_LOGOFF 0x00000040 -#define WTS_EVENT_STATECHANGE 0x00000080 -#define WTS_EVENT_LICENSE 0x00000100 -#define WTS_EVENT_ALL 0x7FFFFFFF -#define WTS_EVENT_FLUSH 0x80000000 - -BOOL WINAPI WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, - LPSTR *ppBuffer, DWORD *pBytesReturned); -BOOL WINAPI WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, - LPTSTR *ppBuffer, DWORD *pBytesReturned); -BOOL WINAPI WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags); -BOOL WINAPI WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait); -BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, - PWTS_SESSION_INFOW *ppSessionInfo, - PDWORD pCount); -BOOL WINAPI WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, - PWTS_SESSION_INFOA *ppSessionInfo, - PDWORD pCount); -void WINAPI WTSFreeMemory(PVOID pMemory); - -#ifdef UNICODE -#define WTSEnumerateSessions WTSEnumerateSessionsW -#define WTSQuerySessionInformation WTSQuerySessionInformationW -#else -#define WTSEnumerateSessions WTSEnumerateSessionsA -#define WTSQuerySessionInformation WTSQuerySessionInformationA -#endif - -BOOL WTSSendMessageA( - HANDLE hServer, - DWORD SessionId, - LPSTR pTitle, - DWORD TitleLength, - LPSTR pMessage, - DWORD MessageLength, - DWORD Style, - DWORD Timeout, - DWORD *pResponse, - BOOL bWait -); - -BOOL WTSSendMessageW( - HANDLE hServer, - DWORD SessionId, - LPWSTR pTitle, - DWORD TitleLength, - LPWSTR pMessage, - DWORD MessageLength, - DWORD Style, - DWORD Timeout, - DWORD *pResponse, - BOOL bWait -); - -#ifdef UNICODE -#define WTSSendMessage WTSSendMessageW -#else -#define WTSSendMessage WTSSendMessageA -#endif - -#endif /* _WIN32_WINNT >= 0x0500 */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WTSAPI32_H */ +#ifndef _WTSAPI32_H +#define _WTSAPI32_H +#if __GNUC__ >= 3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if (_WIN32_WINNT >= 0x0501) + // session notification message +#define WM_WTSSESSION_CHANGE 0x02B1 + +typedef enum _WTS_INFO_CLASS { + WTSInitialProgram = 0, + WTSApplicationName = 1, + WTSWorkingDirectory = 2, + WTSOEMId = 3, + WTSSessionId = 4, + WTSUserName = 5, + WTSWinStationName = 6, + WTSDomainName = 7, + WTSConnectState = 8, + WTSClientBuildNumber = 9, + WTSClientName = 10, + WTSClientDirectory = 11, + WTSClientProductId = 12, + WTSClientHardwareId = 13, + WTSClientAddress = 14, + WTSClientDisplay = 15, + WTSClientProtocolType = 16, + WTSIdleTime = 17, + WTSLogonTime = 18, + WTSIncomingBytes = 19, + WTSOutgoingBytes = 20, + WTSIncomingFrames = 21, + WTSOutgoingFrames = 22, + WTSClientInfo = 23, + WTSSessionInfo = 24 +} WTS_INFO_CLASS; + +typedef enum _WTS_CONNECTSTATE_CLASS { + WTSActive, + WTSConnected, + WTSConnectQuery, + WTSShadow, + WTSDisconnected, + WTSIdle, + WTSListen, + WTSReset, + WTSDown, + WTSInit +} WTS_CONNECTSTATE_CLASS; + + // session notification message flags +#define WTS_CONSOLE_CONNECT 0x1 +#define WTS_CONSOLE_DISCONNECT 0x2 +#define WTS_REMOTE_CONNECT 0x3 +#define WTS_REMOTE_DISCONNECT 0x4 +#define WTS_SESSION_LOGON 0x5 +#define WTS_SESSION_LOGOFF 0x6 +#define WTS_SESSION_LOCK 0x7 +#define WTS_SESSION_UNLOCK 0x8 +#define WTS_SESSION_REMOTE_CONTROL 0x9 + + // WTSRegisterSessionNotifiction flags +#define NOTIFY_FOR_THIS_SESSION 0 +#define NOTIFY_FOR_ALL_SESSIONS 1 + +BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags); +BOOL WINAPI WTSUnRegisterSessionNotification(HWND hWnd); +BOOL WINAPI WTSQueryUserToken(ULONG SessionId, PHANDLE pToken); + +#endif /* _WIN32_WINNT >= 0x0501 */ + +#if (_WIN32_WINNT >= 0x0500) + +typedef struct _WTS_SESSION_INFOW { + DWORD SessionId; + LPWSTR pWinStationName; + WTS_CONNECTSTATE_CLASS State; +} WTS_SESSION_INFOW, *PWTS_SESSION_INFOW; + +typedef struct _WTS_SESSION_INFOA { + DWORD SessionId; + LPSTR pWinStationName; + WTS_CONNECTSTATE_CLASS State; +} WTS_SESSION_INFOA, *PWTS_SESSION_INFOA; + +#ifdef UNICODE +#define WTS_SESSION_INFO WTS_SESSION_INFOW +#define PWTS_SESSION_INFO PWTS_SESSION_INFOW +#else +#define WTS_SESSION_INFO WTS_SESSION_INFOA +#define PWTS_SESSION_INFO PWTS_SESSION_INFOA +#endif + + // WTSWaitSystemEvent local server handle +#define WTS_CURRENT_SERVER_HANDLE 0 +#define WTS_CURRENT_SESSION ((DWORD)-1) + + // WTSWaitSystemEvent flags +#define WTS_EVENT_NONE 0x00000000 +#define WTS_EVENT_CREATE 0x00000001 +#define WTS_EVENT_DELETE 0x00000002 +#define WTS_EVENT_RENAME 0x00000004 +#define WTS_EVENT_CONNECT 0x00000008 +#define WTS_EVENT_DISCONNECT 0x00000010 +#define WTS_EVENT_LOGON 0x00000020 +#define WTS_EVENT_LOGOFF 0x00000040 +#define WTS_EVENT_STATECHANGE 0x00000080 +#define WTS_EVENT_LICENSE 0x00000100 +#define WTS_EVENT_ALL 0x7FFFFFFF +#define WTS_EVENT_FLUSH 0x80000000 + +BOOL WINAPI WTSQuerySessionInformationA(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, + LPSTR *ppBuffer, DWORD *pBytesReturned); +BOOL WINAPI WTSQuerySessionInformationW(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, + LPTSTR *ppBuffer, DWORD *pBytesReturned); +BOOL WINAPI WTSWaitSystemEvent(HANDLE hServer, DWORD EventMask, DWORD* pEventFlags); +BOOL WINAPI WTSDisconnectSession(HANDLE hServer, DWORD SessionId, BOOL bWait); +BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, + PWTS_SESSION_INFOW *ppSessionInfo, + PDWORD pCount); +BOOL WINAPI WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, + PWTS_SESSION_INFOA *ppSessionInfo, + PDWORD pCount); +void WINAPI WTSFreeMemory(PVOID pMemory); + +#ifdef UNICODE +#define WTSEnumerateSessions WTSEnumerateSessionsW +#define WTSQuerySessionInformation WTSQuerySessionInformationW +#else +#define WTSEnumerateSessions WTSEnumerateSessionsA +#define WTSQuerySessionInformation WTSQuerySessionInformationA +#endif + +BOOL WTSSendMessageA( + HANDLE hServer, + DWORD SessionId, + LPSTR pTitle, + DWORD TitleLength, + LPSTR pMessage, + DWORD MessageLength, + DWORD Style, + DWORD Timeout, + DWORD *pResponse, + BOOL bWait +); + +BOOL WTSSendMessageW( + HANDLE hServer, + DWORD SessionId, + LPWSTR pTitle, + DWORD TitleLength, + LPWSTR pMessage, + DWORD MessageLength, + DWORD Style, + DWORD Timeout, + DWORD *pResponse, + BOOL bWait +); + +#ifdef UNICODE +#define WTSSendMessage WTSSendMessageW +#else +#define WTSSendMessage WTSSendMessageA +#endif + +#endif /* _WIN32_WINNT >= 0x0500 */ + +#ifdef __cplusplus +} +#endif + +#endif /* _WTSAPI32_H */ diff --git a/README.md b/README.md index b2015ad..63acf44 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Test ---- To test this driver run one of the installation programs: - http://www.acc.umu.se/~bosse/ext2fsd/0.70/Ext2Fsd-0.70b2-setup.exe for Windows 10. - http://www.acc.umu.se/~bosse/ext2fsd/0.70/Ext2Fsd-0.70b1-setup-xp.exe for Windows XP - Windows 8.1. + http://www.acc.umu.se/~bosse/ext2fsd/0.70/Ext2Fsd-0.70b2-setup.exe for Windows 8 - Windows 10. + http://www.acc.umu.se/~bosse/ext2fsd/0.70/Ext2Fsd-0.70b1-setup-xp.exe for Windows XP - Windows 7. If you compile the driver yourself you only need to run the installation program once, then you can - copy your driver over the old in \windows\system32\drivers. + copy your driver file over the old in \windows\system32\drivers. Now you can read and write ext4 filesystems using the new features metadata checksums and 64-bit blocknumbers from Windows. (sorry I can not sign drivers so you need to turn of Windows checking for that during testing)