1
0
mirror of https://github.com/bobranten/Ext4Fsd.git synced 2025-10-29 21:18:30 -05:00

Ext4Fsd master

This commit is contained in:
Bo Brantén
2020-01-19 19:08:53 +01:00
commit 7b368ccf09
272 changed files with 143529 additions and 0 deletions

524
Ext2Srv/Ext2Pipe.cpp Normal file
View File

@@ -0,0 +1,524 @@
#include <Ext2Srv.h>
#include <Sddl.h>
#include <Ext2Pipe.h>
/*
* 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 = 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);
}

49
Ext2Srv/Ext2Pipe.h Normal file
View File

@@ -0,0 +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()
#endif // EXT2_SRV_PIPE_H

579
Ext2Srv/Ext2Srv.cpp Normal file
View File

@@ -0,0 +1,579 @@
#include <Ext2Srv.h>
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 = 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;
}

128
Ext2Srv/Ext2Srv.h Normal file
View File

@@ -0,0 +1,128 @@
#ifndef _EXT2_SRV_INCLUDE_
#define _EXT2_SRV_INCLUDE_
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <tchar.h>
#include <windows.h>
#include <crtdbg.h>
#include <process.h>
#include <WtsApi32.h>
#include <dbt.h>
#include <shellapi.h>
/*
* 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_ */

BIN
Ext2Srv/Ext2Srv.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

125
Ext2Srv/Ext2Srv.rc Normal file
View File

@@ -0,0 +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 <matt@ext2fsd.com>"
VALUE "CompanyName", "www.ext2fsd.com"
VALUE "FileDescription", "Ext2Fsd Service Management"
VALUE "FileVersion", "1.4.7.9"
VALUE "InternalName", "Ext2Srv.exe"
VALUE "LegalCopyright", "Matt Wu <matt@ext2fsd.com>"
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

28
Ext2Srv/Ext2Srv.sln Normal file
View File

@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ext2Srv", "Ext2Srv.vcproj", "{A18F670C-DA85-43F6-8620-99A2DD8CEF1A}"
EndProject
Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 1
SccProjectUniqueName0 = Ext2Srv.vcproj
SccProjectName0 = Ext2Srv
SccLocalPath0 = .
SccProvider0 = MSSCCI:Perforce\u0020P4\u0020SCM
CanCheckoutShared = true
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A18F670C-DA85-43F6-8620-99A2DD8CEF1A}.Debug|Win32.ActiveCfg = Debug|Win32
{A18F670C-DA85-43F6-8620-99A2DD8CEF1A}.Debug|Win32.Build.0 = Debug|Win32
{A18F670C-DA85-43F6-8620-99A2DD8CEF1A}.Release|Win32.ActiveCfg = Release|Win32
{A18F670C-DA85-43F6-8620-99A2DD8CEF1A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

263
Ext2Srv/Ext2Srv.vcproj Normal file
View File

@@ -0,0 +1,263 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="Ext2Srv"
ProjectGUID="{A18F670C-DA85-43F6-8620-99A2DD8CEF1A}"
RootNamespace="Ext2Srv"
SccProjectName="Ext2Srv"
SccLocalPath="."
SccProvider="MSSCCI:Perforce P4 SCM"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release\X86\"
IntermediateDirectory=".\Release\X86\"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName="./Release\X86/Ext2Srv.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE; _CRT_SECURE_NO_WARNINGS;"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile="./Release/X86/Ext2Srv.pch"
AssemblerListingLocation="./Release/X86/"
ObjectFile="./Release/X86/"
ProgramDataBaseFileName="./Release/X86/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2052"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="WtsApi32.lib shlwapi.lib vs9cmt.lib vs9cpmt.lib"
OutputFile="./Release/X86/Ext2Srv.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".\Libraries\x86\;"
IgnoreAllDefaultLibraries="true"
GenerateDebugInformation="false"
ProgramDatabaseFile="./Release/X86/Ext2Srv.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile="./Release/X86/Ext2Srv.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName="./Debug/X86/Ext2Srv.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories=".;"
PreprocessorDefinitions="NDEBUG;_CONSOLE; _CRT_SECURE_NO_WARNINGS;"
StringPooling="true"
BasicRuntimeChecks="3"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile="./Debug/X86/Ext2Srv.pch"
BrowseInformation="1"
BrowseInformationFile="./Debug/X86/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2052"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="true"
AdditionalDependencies="WtsApi32.lib shlwapi.lib vs9cmtd.lib vs9cpmtd.lib"
OutputFile="./Debug/X86/Ext2Srv.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".\Libraries\x86\;"
IgnoreAllDefaultLibraries="true"
GenerateDebugInformation="true"
ProgramDatabaseFile="./Debug/X86/Ext2Srv.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile="./Debug/X86/Ext2Srv.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\Ext2Pipe.cpp"
>
</File>
<File
RelativePath=".\Ext2Pipe.h"
>
</File>
<File
RelativePath="Ext2Srv.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="Ext2Srv.h"
>
</File>
<File
RelativePath=".\Ext2Srv.ico"
>
</File>
<File
RelativePath=".\Ext2Srv.rc"
>
</File>
<File
RelativePath=".\Mount.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,140 @@
/*
tlhelp32.h - Include file for Tool help functions.
Written by Mumit Khan <khan@nanotech.wisc.edu>
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 */

View File

@@ -0,0 +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 */

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

11
Ext2Srv/MAKEFILE Normal file
View File

@@ -0,0 +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

466
Ext2Srv/Mount.cpp Normal file
View File

@@ -0,0 +1,466 @@
#include <Ext2Srv.h>
#include <tlhelp32.h>
#include <Sddl.h>
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 = _tcslen(s), lt = _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 + _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);
}

Binary file not shown.

12
Ext2Srv/SOURCES Normal file
View File

@@ -0,0 +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