Example #1
0
int main(int argc, char * * argv)
{
   APIRET rc;
   AEFS_SETPARAMS params;
   ULONG cbParams = sizeof(params);
   char * p = params.szParams;
   int c, i;

   for (c = i = 1; i < argc; i++) {
      c += 1 + strlen(argv[i]);
      if (c > sizeof(params.szParams)) {
         fprintf(stderr, "%s: parameter list too long\n", argv[0]);
         return 1;
      }
      strcpy(p, argv[i]);
      p = strchr(p, 0) + 1;
   }
   *p = 0;

   rc = DosFSCtl(
      NULL, 0, NULL,
      &params, sizeof(params), &cbParams,
      FSCTL_AEFS_SETPARAMS,
      (PSZ) AEFS_IFS_NAME,
      (HFILE) -1,
      FSCTL_FSDNAME);
   if (rc) {
      fprintf(stderr, "%s: error settings parameters, rc = %ld\n",
         argv[0], rc);
      return 1;
   }

   return 0;
}
Example #2
0
/* Call the HFS driver with DosFSCtl */
APIRET do_FSCtl(PVOID pData, ULONG cbData, PULONG pcbData,
		PVOID pParms, ULONG cbParms, PULONG pcbParms,
		ULONG function)
{
  char name[10];

  strncpy(name, FS_NAME, sizeof(name));
  return DosFSCtl(pData, cbData, pcbData, pParms, cbParms, pcbParms,
		  function, name, -1, FSCTL_FSDNAME);
}
Example #3
0
int VFSENTRY vfs_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, int size, int *err_no) {
    APIRET rc;
    ULONG  dataio, parmio;
    short  err;
    struct fsctl_msg  sig;

    *err_no = EPERM;

    //
    // We first check that the file descriptor refers to a file located on a file system
    // managed by ext2-os2.ifs
    //
    err    = NO_ERROR;
    dataio = 0;
    parmio = 0;
    if ((rc = DosFSCtl(
                       &sig,  sizeof(struct fsctl_msg), &dataio,
                       &err,  sizeof(short), &parmio,
                       FSCTL_ERROR_INFO,  NULL,
                       (HFILE)fd,  FSCTL_HANDLE)) != NO_ERROR) {
        return -1;
    }
    if (memcmp(&sig, &ext2_os2_magic, sizeof(struct fsctl_msg)) != 0) {
        return -1;
    }


    //
    // We issue the ioctl call
    //
    dataio = 0;
    if ((rc = DosFSCtl(
                       (void *)arg, size, &dataio,
                       0, 0, 0,
                       cmd, NULL,
                       (HFILE)fd,  FSCTL_HANDLE)) != NO_ERROR) {
        return -1;
    }

    *err_no = 0;
    return 0;
}
Example #4
0
int VFSENTRY vfs_fstat(int fd,              // in: valid OS/2 standard file handle (DosOpen)
                       struct vfs_stat *s)  // in/out: contains i-node information.
{
    APIRET rc;
    ULONG  dataio, parmio;
    short  err;
    struct fsctl_msg  sig;

    //
    // We first check that the file descriptor refers to a file located on a file system
    // managed by ext2-os2.ifs
    //
    err    = NO_ERROR;
    dataio = 0;
    parmio = sizeof(short);
    if ((rc = DosFSCtl(
                       &sig,  sizeof(struct fsctl_msg), &dataio,
                       &err,  sizeof(short), &parmio,
                       FSCTL_ERROR_INFO,  NULL,
                       (HFILE)fd,  FSCTL_HANDLE)) != NO_ERROR) {
        return rc;
    }
    if (memcmp(&sig, &ext2_os2_magic, sizeof(struct fsctl_msg)) != 0) {
        return ERROR_INVALID_PARAMETER;
    }


    //
    // We then ask ext2-os2.ifs to do the fstat() call
    //
    dataio = 0;
    parmio = 0;
    if ((rc = DosFSCtl(
                       s,  sizeof(struct vfs_stat), &dataio,
                       NULL,  0, &parmio,
                       EXT2_OS2_FSTAT,  NULL,
                       (HFILE)fd,  FSCTL_HANDLE)) != NO_ERROR) {
        return rc;
    }

    return 0;
}
Example #5
0
/**
 * Check if the given IFS was loaded
 *
 * @param[in] fsdName FSD name
 * @return Non-zero if loaded, 0 if not loaded
 * @remark FSD name is the file-system driver name exported by the file-system
 *         driver. This name may be different from the filename of the
 *         file-system driver and/or the file-system name in the boot sector.
 */
int checkIfs( const char *fsdName )
{
    ULONG ulDataLen = 0;
    ULONG ulParamLen = 0;
    ULONG rc;

    rc = DosFSCtl( NULL, 0, &ulDataLen, NULL, 0, &ulParamLen,
                   0, fsdName, -1, FSCTL_FSDNAME );

    return rc != ERROR_INVALID_FSD_NAME;
}
Example #6
0
int VFSENTRY vfs_stat(const char *pathname,     // in: filename (as with DosOpen)
                      struct vfs_stat *s)       // out: i-node information
{
    APIRET rc;
    ULONG  dataio, parmio;
    short  err;
    struct fsctl_msg  sig;

    //
    // We first check that the file descriptor refers to a file located on a file system
    // managed by ext2-os2.ifs
    //
    err    = NO_ERROR;
    dataio = 0;
    parmio = sizeof(short);
    if ((rc = DosFSCtl(
                       &sig,  sizeof(struct fsctl_msg), &dataio,
                       &err,  sizeof(short), &parmio,
                       FSCTL_ERROR_INFO,  (PSZ)pathname,
                       (HFILE)(-1),  FSCTL_PATHNAME)) != NO_ERROR) {
        return rc;
    }
    if (memcmp(&sig, &ext2_os2_magic, sizeof(struct fsctl_msg)) != 0) {
        return ERROR_INVALID_PARAMETER;
    }

    //
    // We then ask ext2-os2.ifs to do the stat() call
    //
    dataio = sizeof(struct vfs_stat);
    parmio = 0;
    if ((rc = DosFSCtl(
                       s,  sizeof(struct vfs_stat), &dataio,
                       NULL,  0, &parmio,
                       EXT2_OS2_STAT,  (PSZ)pathname,
                       (HFILE)(-1),  FSCTL_PATHNAME)) != NO_ERROR) {
        return rc;
    }

    return 0;
}
Example #7
0
void CtrlCHandler(int signal)
{
    BOOL fActive;
    ULONG ulParmSize;
    ULONG ulDataSize;
    APIRET rc;

    fActive = FALSE;
    ulParmSize = sizeof fActive;
    ulDataSize = 0;
    rc = DosFSCtl(
             NULL, 0, &ulDataSize,
             (PVOID)&fActive, ulParmSize, &ulParmSize,
             FAT32_SETMESSAGE, "FAT32", -1, FSCTL_FSDNAME);

    printf("\nprogram aborted!\n");
    exit(1);
}
Example #8
0
VOID APIENTRY LWThread(ULONG ulArg)
{
APIRET rc;
ULONG  ulParmSize;
ULONG  ulDataSize;

   rc = DosSetPriority(PRTYS_THREAD,
      pOptions->bLWPrio, 0, 0);

   ulParmSize = sizeof (LWOPTS);
   ulDataSize = 0;

   rc = DosFSCtl(NULL, 0, &ulDataSize,
      (PVOID)pOptions, ulParmSize, &ulParmSize,
      FAT32_DOLW, "FAT32", -1, FSCTL_FSDNAME);

   rc = rc;

   pOptions->fTerminate = TRUE;
}
Example #9
0
VOID APIENTRY EMThread(ULONG ulArg)
{
APIRET rc;
ULONG  ulParmSize;
ULONG  ulDataSize;

#if 1
   rc = DosSetPriority(PRTYS_THREAD,
      PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0);
#else
   rc = DosSetPriority(PRTYS_THREAD,
      PRTYC_FOREGROUNDSERVER, PRTYD_MAXIMUM, 0);
#endif

   ulParmSize = sizeof (LWOPTS);
   ulDataSize = 0;

   rc = DosFSCtl(NULL, 0, &ulDataSize,
      (PVOID)pOptions, ulParmSize, &ulParmSize,
      FAT32_EMERGTHREAD, "FAT32", -1, FSCTL_FSDNAME);
   if (rc)
      printf("EMThread: rc = %u\n", rc);
}
Example #10
0
int VFSENTRY vfs_link(const char *src,      // in: source file name to be linked
                      const char *dst)      // in: file name for the new link
{
    APIRET rc;
    ULONG  dataio, parmio;
    short  err;
    struct fsctl_msg  sig;
    char dst_norm[CCHMAXPATH];

    //
    // We check that the source path refers to a file located on a file system
    // managed by ext2-os2.ifs
    //
    err    = NO_ERROR;
    dataio = 0;
    parmio = sizeof(short);
    if ((rc = DosFSCtl(
                  &sig,  sizeof(struct fsctl_msg), &dataio,
                  &err,  sizeof(short), &parmio,
                  FSCTL_ERROR_INFO,  (PSZ)src,
                  (HFILE)(-1),  FSCTL_PATHNAME)) != NO_ERROR) {
        return rc;
    }
    if (memcmp(&sig, &ext2_os2_magic, sizeof(struct fsctl_msg)) != 0) {
        return ERROR_INVALID_PARAMETER;
    }

    //
    // We check that the destination path refers to a file located on a file system
    // managed by ext2-os2.ifs
    //
    err    = NO_ERROR;
    dataio = 0;
    parmio = sizeof(short);
    if ((rc = DosFSCtl(
                  &sig,  sizeof(struct fsctl_msg), &dataio,
                  &err,  sizeof(short), &parmio,
                  FSCTL_ERROR_INFO,  (PSZ)dst,
                  (HFILE)(-1),  FSCTL_PATHNAME)) != NO_ERROR) {
        return rc;
    }
    if (memcmp(&sig, &ext2_os2_magic, sizeof(struct fsctl_msg)) != 0) {
        return ERROR_INVALID_PARAMETER;
    }

    //
    // We get the normalized destination path name
    //
    dataio = CCHMAXPATH;
    if ((rc = DosFSCtl(
                  dst_norm,  CCHMAXPATH, &dataio,
                  0, 0, 0,
                  EXT2_OS2_NORMALIZE_PATH,  (PSZ)dst,
                  (HFILE)(-1),  FSCTL_PATHNAME)) != NO_ERROR) {
        return rc;
    }

    //
    // We then ask ext2-os2.ifs to do the link() call
    //
    dataio = strlen(dst_norm) + 1;
    if ((rc = DosFSCtl(
                  dst_norm,  dataio, &dataio,
                  0, 0, 0,
                  EXT2_OS2_LINK,  (PSZ)src,
                  (HFILE)(-1),  FSCTL_PATHNAME)) != NO_ERROR) {
        return rc;
    }

    return 0;
}
Example #11
0
int main(INT iArgc, PSZ Argv[])
{
    APIRET rc;
    ULONG  ulTimeOut = 10L;
    ULONG ulParmSize;
    ULONG ulDataSize;
    FILE *fLog;
    BOOL fActive;
    BOOL fSilent = FALSE;
    BOOL fForce = FALSE;
    INT  iArg;

    signal(SIGINT, CtrlCHandler);
    signal(SIGTERM, CtrlCHandler);
    signal(SIGBREAK, CtrlCHandler);

    fActive = 1;
    for (iArg = 1; iArg < iArgc; iArg++)
    {
        if (!stricmp(Argv[iArg], "off"))
        {
            fActive = FALSE;
            break;
        }
        if (isdigit(Argv[iArg][0]))
            fActive = atoi(Argv[iArg]);
        if (!stricmp(Argv[iArg], "/S"))
            fSilent = TRUE;
        if (!stricmp(Argv[iArg], "/F"))
            fForce = TRUE;
    }


    ulParmSize = sizeof fActive;
    rc = DosFSCtl(
             NULL, 0, &ulDataSize,
             (PVOID)&fActive, ulParmSize, &ulParmSize,
             FAT32_SETMESSAGE, "FAT32", -1, FSCTL_FSDNAME);

    if (!fActive)
        return 0;

    rc = DosSetPriority(PRTYS_PROCESS,
                        PRTYC_FOREGROUNDSERVER, 0, 0);

    fLog = fopen("FAT32.LOG", "wb");
    for (;;)
    {
        if (kbhit())
            break;
        ulParmSize = sizeof ulTimeOut;
        ulDataSize = sizeof szBuffer;

        rc = DosFSCtl(
                 (PVOID)szBuffer, ulDataSize, &ulDataSize,
                 (PVOID)&ulTimeOut, ulParmSize, &ulParmSize,
                 FAT32_GETLOGDATA, "FAT32", -1, FSCTL_FSDNAME);

        if (rc == ERROR_NOT_SUPPORTED)
        {
            printf("Not supported function\n");
            break;
        }
        if (!rc || rc == 111)
        {
            if (!fSilent)
                printf(szBuffer);
            if (fLog)
            {
                fputs(szBuffer, fLog);
                if (fForce)
                {
                    INT iHandle;
                    fflush(fLog);
                    iHandle = dup(fileno(fLog));
                    close(iHandle);
                }
            }
        }
        else if (rc != 0x8001)
        {
            printf("SYS%4.4d\n", rc);
            break;
        }
    }

    fActive = FALSE;
    ulParmSize = sizeof fActive;
    rc = DosFSCtl(
             NULL, 0, &ulDataSize,
             (PVOID)&fActive, ulParmSize, &ulParmSize,
             FAT32_SETMESSAGE, "FAT32", -1, FSCTL_FSDNAME);

    fclose(fLog);
    return 0;
}
Example #12
0
main(int argc, char *argv[])
{
        int rc;
	struct LWPARMS lwparms;
	unsigned long cbData = sizeof(struct LWPARMS);
	unsigned long datalen = 0;
	unsigned long dummyp = 0;
	char *string;
	char *token;
// BEGIN D230860
	int i;

	/*
	 * Initialize lwparms in case we're only modifying minfree or maxfree
	 */
	rc = DosFSCtl(  (PVOID) &lwparms,	/* data area */
			cbData,		/* size of data */
			&datalen,	/* returned data length */
			NULL,		/* parameter list */
			0,		/* size of parameter list */
			&dummyp,	/* return parm length */
			JFSCTL_LW_GET,	/* function code */
			"JFS",		/* target file system */
			-1,		/* file handle */
			FSCTL_FSDNAME);	/* method of file system id */
// END D230860

	/* Parse same as IFS command line.  /L*: is optional
	 */
	if (argc == 1)
	{
		return report();
	}
	for (i = 1; i < argc; i++)				// D2308860
	{
		string = argv[i];
		if ((*string == '/') || (*string == '-'))
		{
			string++;
// BEGIN D230860
			if ((*string == 'm') || (*string == 'M'))
			{
				string++;
				if ((*string == 'i') || (*string == 'I'))
				{
					/* MINFREE! */
					while (*(++string) && (*string != ':'));
					if (*string)
						string++;
					lwparms.MinFree = strtoul(string, 0, 0);
				}
				else if ((*string == 'a') || (*string == 'A'))
				{
					/* MAXFREE! */
					while (*(++string) && (*string != ':'));
					if (*string)
						string++;
					lwparms.MaxFree = strtoul(string, 0, 0);
				}
				else
				{
					usage();
					return ERROR_INVALID_PARAMETER;
				}
				continue;
			}
// END D230860
			if ((*string != 'l') && (*string != 'L'))
			{
				usage();
				return ERROR_INVALID_PARAMETER;
			}
			while (*(++string) && (*string != ':'));
			if (*string)
				string++;	/* skip past colon */
		}
		/* string is pointing just past /LAZYWRITE: if it was there */

		if ((strcmp(string, "OFF") == 0) ||
		    (strcmp(string, "off") == 0))
		{
			lwparms.LazyOff = 1;
			lwparms.SyncTime = 1;
			lwparms.MaxAge = 0;
			lwparms.BufferIdle = 0;
			continue;				// D230860
		}
		lwparms.LazyOff = 0;

		token = strtok(string, ",");

		if (token == 0)
		{
			/* No parameters */
			usage();
			return ERROR_INVALID_PARAMETER;
		}

		if ((lwparms.SyncTime = strtoul(token,0,0)) <= 0)
			lwparms.SyncTime = 1;

		token = strtok(0, ",");

		if (token == 0)
		{
			lwparms.MaxAge = lwparms.SyncTime << 2;
			lwparms.BufferIdle = lwparms.SyncTime >> 3;
			continue;				// D230860
		}

		if ((lwparms.MaxAge = strtoul(token,0,0)) < 0)
			lwparms.MaxAge = 0;

		token = strtok(0, ",");

		if (token == 0)
		{
			lwparms.BufferIdle = lwparms.SyncTime >> 3;
			continue;				// D230860
		}
Example #13
0
BOOL LoadTranslateTable(VOID)
{
APIRET rc;
ULONG ulParmSize;
BYTE   rgData[256];
PBYTE  pIn;
USHORT rgTranslate[256];
PUSHORT pOut;
UconvObject  uconv_object = NULL;
INT iIndex;
size_t       in_bytes_left;
size_t       uni_chars_left;
size_t       num_subs;
ULONG rgCP[3];
ULONG cbCP;

   rc = DosLoadModule(rgData, sizeof rgData, "UCONV.DLL", &hModLang);
   if (rc)
      {
      printf("No NLS support found (%s does not load).\n", rgData);
      printf("No UNICODE translate table loaded!\n");
      return TRUE;
      }
   rc = DosQueryProcAddr(hModLang, 0L,
      "UniCreateUconvObject", (PFN *)&pUniCreateUconvObject);
   if (rc)
      {
      printf("ERROR: Could not find address of UniCreateUconvObject.\n");
      return FALSE;
      }
   rc = DosQueryProcAddr(hModLang, 0L,
      "UniUconvToUcs", (PFN *)&pUniUconvToUcs);
   if (rc)
      {
      printf("ERROR: Could not find address of UniUconvToUcs.\n");
      return FALSE;
      }

   rc = DosQueryCp(sizeof rgCP, rgCP, &cbCP);
   if (f32Parms.ulCurCP == rgCP[0])
      return FALSE;

   if (f32Parms.ulCurCP)
      {
      BYTE chChar;
      printf("Loaded unicode translate table is for CP %lu\n", f32Parms.ulCurCP);
      printf("Current CP is %lu\n", rgCP[0]);
      printf("Would you like to reload the translate table for this CP [Y/N]? ");
      fflush(stdout);

      for (;;)
         {
         chChar = getch();
         switch (chChar)
            {
            case 'y':
            case 'Y':
               chChar = 'Y';
               break;
            case 'n':
            case 'N':
               chChar = 'N';
               break;
            default :
               DosBeep(660, 10);
               continue;
            }
         printf("%c\n", chChar);
         break;
         }
      if (chChar == 'N')
         return FALSE;
      }

   for (iIndex = 0; iIndex < 256; iIndex++)
      rgData[iIndex] = iIndex;

   rc = pUniCreateUconvObject((UniChar *)L"", &uconv_object);
   if (rc != ULS_SUCCESS)
      {
      printf("UniCreateUconvObject error: return code = %u\n", rc);
      return FALSE;
      }

   pIn  = rgData;
   in_bytes_left = sizeof rgData;
   pOut = rgTranslate;
   uni_chars_left = sizeof rgTranslate / sizeof (USHORT);

   rc = pUniUconvToUcs(uconv_object,
      (PVOID *)&pIn,
      &in_bytes_left,
      &pOut,
      &uni_chars_left,
      &num_subs);

   if (rc != ULS_SUCCESS)
      {
      printf("UniUconvToUcs failed, rc = %u\n", rc);
      return FALSE;
      }


   ulParmSize = sizeof rgTranslate;
   rc = DosFSCtl(NULL, 0, NULL,
               rgTranslate, ulParmSize, &ulParmSize,
               FAT32_SETTRANSTABLE, "FAT32", -1, FSCTL_FSDNAME);
   if (rc)
      {
      printf("Unable to set translate table for current Codepage.\n");
      return FALSE;
      }

   f32Parms.ulCurCP = rgCP[0];
   printf("Unicode translate table for CP %lu loaded.\n", rgCP[0]);
   DosFreeModule(hModLang);
   return TRUE;
}
Example #14
0
INT main(INT iArgc, PSZ rgArgv[])
{
APIRET rc;
ULONG ulParmSize;
ULONG ulDataSize;
BYTE  bPrevPrio;

   DoCheckDisk(FALSE);


   InitProg(iArgc, rgArgv);
   if (fActive)
      DosExit(EXIT_PROCESS, 0);

   if (fForeGround)
      {
      DoCheckDisk(TRUE);
      if (!f32Parms.usCacheSize)
         printf("Cache size has been set to zero, lazy writer will not be started!\n");
      else if (fLoadDeamon)
         StartMe(rgArgv[0]);
      DosExit(EXIT_PROCESS, 0);
      }

   rc = DosFSCtl(NULL, 0, &ulDataSize,
                 NULL, 0, &ulParmSize,
      FAT32_STOPLW, "FAT32", -1, FSCTL_FSDNAME);

   rc = DosFSCtl(NULL, 0, &ulDataSize,
                 NULL, 0, &ulParmSize,
      FAT32_STARTLW, "FAT32", -1, FSCTL_FSDNAME);
   if (rc)
      {
      printf("Starting LW failed, rc = %d\n", rc);
      exit(1);
      }

   signal(SIGBREAK, Handler);
   signal(SIGTERM, Handler);
   signal(SIGINT, Handler);

   rc = DosCreateThread(&pOptions->ulEMTID, EMThread, 0L, 0, 8196);
   if (rc)
      printf("DosCreateThread failed, rc = %d\n", rc);

   rc = DosCreateThread(&pOptions->ulLWTID, LWThread, 0L, 0, 8196);
   if (rc)
      printf("DosCreateThread failed, rc = %d\n", rc);

   ulParmSize = sizeof f32Parms;
   rc = DosFSCtl(
      NULL, 0, &ulDataSize,
      (PVOID)&f32Parms, ulParmSize, &ulParmSize,
      FAT32_SETPARMS, "FAT32", -1, FSCTL_FSDNAME);

   bPrevPrio = pOptions->bLWPrio;
   while (!pOptions->fTerminate)
      {
      if (bPrevPrio != pOptions->bLWPrio)
         {
         DosSetPriority(PRTYS_THREAD,
            pOptions->bLWPrio, 0, pOptions->ulLWTID);
         bPrevPrio = pOptions->bLWPrio;
         }
      DosSleep(5000);
      }

   DosExit(EXIT_PROCESS, 0);

   return 0;
}
Example #15
0
VOID InitProg(INT iArgc, PSZ rgArgv[])
{
APIRET    rc;
BYTE      szTranslate[256];
INT       iArg;
ULONG     ulLVB;
USHORT    uscbLVB;
ULONG     ulDataSize;
ULONG     ulParmSize;
BOOL      fSetParms = FALSE;
ULONG     ulParm;


   memset(szTranslate, 0, sizeof szTranslate);

   /*
      Determine if we run in the foreground
   */
   rc = VioGetBuf(&ulLVB, &uscbLVB, (HVIO)0);
   if (rc)
      fForeGround = FALSE;
   else
      fForeGround = TRUE;

   if (fForeGround)
      printf("FAT32 cache helper version %s.\n", FAT32_VERSION);
   else
      WriteLogMessage("FAT32 task detached");

   rc = DosGetNamedSharedMem((PVOID *)&pOptions, SHAREMEM, PAG_READ|PAG_WRITE);
   if (!rc)
      {
      fActive = TRUE;
      WriteLogMessage("Shared memory found!");
      }
   else
      {
      rc = DosAllocSharedMem((PVOID *)&pOptions, SHAREMEM, sizeof (LWOPTS), PAG_COMMIT|PAG_READ|PAG_WRITE);
      if (rc)
         DosExit(EXIT_PROCESS, 1);
      memset(pOptions, 0, sizeof pOptions);
      pOptions->bLWPrio = PRTYC_IDLETIME;
      WriteLogMessage("Shared memory allocated!");
      }

   ulDataSize = sizeof f32Parms;
   rc = DosFSCtl(
      (PVOID)&f32Parms, ulDataSize, &ulDataSize,
      NULL, 0, &ulParmSize,
      FAT32_GETPARMS, "FAT32", -1, FSCTL_FSDNAME);
   if (rc)
      {
      printf("DosFSCtl, FAT32_GETPARMS failed, rc = %d\n", rc);
      DosExit(EXIT_PROCESS, 1);
      }
   if (strcmp(f32Parms.szVersion, FAT32_VERSION))
      {
      printf("ERROR: FAT32 version (%s) differs from CACHEF32 version (%s)\n", f32Parms.szVersion, FAT32_VERSION);
      DosExit(EXIT_PROCESS, 1);
      }

   for (iArg = 1; iArg < iArgc; iArg++)
      {
      strupr(rgArgv[iArg]);
      if (rgArgv[iArg][0] == '/' || rgArgv[iArg][0] == '-')
         {
         switch (rgArgv[iArg][1])
            {
            case '?' :
               printf("USAGE: CACHEF32 [options]\n");
               printf("/Q (Quit)\n");
               printf("/N do NOT load lazy write deamon.\n");
               printf("/D:diskidle in millisecs.\n");
               printf("/B:bufferidle in millisecs.\n");
               printf("/M:maxage in millisecs.\n");
               printf("/R:d:,n sets read ahead sector count for drive d: to n.\n");
               printf("/FS use short file names internally.\n");
               printf("/FL use long file names internally.\n");
               printf("/L:on|off set lazy writing on or off.\n");
               printf("/P:1|2|3|4 Set priority of Lazy writer\n");
               DosExit(EXIT_PROCESS, 0);
               break;

            case 'P':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("Missing : after /P\n");
                  DosExit(EXIT_PROCESS, 1);
                  }
               if (rgArgv[iArg][3] < '1' ||
                   rgArgv[iArg][3] > '4')
                  {
                  printf("Lazy write priority should be from 1 to 4!\n");
                  DosExit(EXIT_PROCESS, 1);
                  }
               pOptions->bLWPrio = rgArgv[iArg][3] - '0';
               break;


            case 'N':
               fLoadDeamon = FALSE;
               break;

            case 'T':
               printf("The /T option is no longer supported.\n");
               printf("Please read the documentation.\n");
               break;

            case 'Q' :
               if (fActive)
                  {
                  if (pOptions->fTerminate)
                     printf("Terminate request already set!\n");
                  pOptions->fTerminate = TRUE;
                  printf("Terminating CACHEF32.EXE...\n");
                  DosExit(EXIT_PROCESS, 0);
                  }
               printf("/Q is invalid, CACHEF32 is not running!\n");
               DosExit(EXIT_PROCESS, 1);
               break;
            case 'D':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               ulParm = atol(&rgArgv[iArg][3]);
               if (!ulParm)
                  {
                  printf("ERROR: Invalid value in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               f32Parms.ulDiskIdle = ulParm / TIME_FACTOR;
               fSetParms = TRUE;
               break;

            case 'B':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               ulParm = atol(&rgArgv[iArg][3]);
               if (!ulParm)
                  {
                  printf("ERROR: Invalid value in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               f32Parms.ulBufferIdle = ulParm / TIME_FACTOR;
               fSetParms = TRUE;
               break;

            case 'M':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               ulParm = atol(&rgArgv[iArg][3]);
               if (!ulParm)
                  {
                  printf("ERROR: Invalid value in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               f32Parms.ulMaxAge = ulParm / TIME_FACTOR;
               fSetParms = TRUE;
               break;

            case 'R':
               if (rgArgv[iArg][2] != ':')
                  {
                  printf("ERROR: missing : in %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               SetRASectors(&rgArgv[iArg][3]);
               break;
            case 'F':
               if (rgArgv[iArg][2] == 'S')
                  f32Parms.fUseShortNames = TRUE;
               else if (rgArgv[iArg][2] == 'L')
                  f32Parms.fUseShortNames = FALSE;
               else
                  {
                  printf("ERROR: Unknown option %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               fSetParms = TRUE;
               break;

            case 'L':
               if (!stricmp(&rgArgv[iArg][2], ":ON"))
                  {
                  rc = DosFSCtl(NULL, 0, NULL,
                              NULL, 0, NULL,
                     FAT32_STARTLW, "FAT32", -1, FSCTL_FSDNAME);
                  if (rc)
                     printf("Warning: Lazy writing is already active or cachesize is 0!\n");
                  }
               else if (!stricmp(&rgArgv[iArg][2], ":OFF"))
                  {
                  rc = DosFSCtl(NULL, 0, NULL,
                              NULL, 0, NULL,
                     FAT32_STOPLW, "FAT32", -1, FSCTL_FSDNAME);
                  if (rc)
                     printf("Warning: Lazy writing is not active!\n");
                  }
               else
                  {
                  printf("ERROR: Unknown option %s\n", rgArgv[iArg]);
                  DosExit(EXIT_PROCESS, 1);
                  }
               break;

            default :
               printf("ERROR: Unknown option %s\n", rgArgv[iArg]);
               DosExit(EXIT_PROCESS, 1);
               break;
            }

         }
      }

   if (LoadTranslateTable())
      fSetParms = TRUE;

   if (fSetParms)
      {
      if (f32Parms.ulDiskIdle < f32Parms.ulBufferIdle)
         {
         printf("DISKIDLE must be greater than BUFFERIDLE\n");
         DosExit(EXIT_PROCESS, 1);
         }

      ulParmSize = sizeof f32Parms;
      rc = DosFSCtl(
         NULL, 0, &ulDataSize,
         (PVOID)&f32Parms, ulParmSize, &ulParmSize,
         FAT32_SETPARMS, "FAT32", -1, FSCTL_FSDNAME);
      if (rc)
         {
         printf("DosFSCtl FAT32_SETPARMS, failed, rc = %d\n", rc);
         DosExit(EXIT_PROCESS, 1);
         }
      }

   ulDriveMap = GetFAT32Drives();
   if (!fActive)
      {
      if (!ulDriveMap)
         {
         printf("FAT32: No FAT32 partitions found, aborting...\n");
         DosExit(EXIT_PROCESS, 1);
         }
      }



   /*
      Query parms
   */

   if (fActive || !f32Parms.usCacheSize)
      {
      if (fActive)
         {
         printf("CACHEF32 is already running.\n");
         printf("Current priority is %s.\n", rgPriority[pOptions->bLWPrio]);
         }

      if (!f32Parms.fLW)
         printf("LAZY WRITING is NOT active!\n\n");
      else
         {
         printf("\n");
         printf("DISKIDLE  : %lu milliseconds.\n", f32Parms.ulDiskIdle * TIME_FACTOR);
         printf("BUFFERIDLE: %lu milliseconds.\n", f32Parms.ulBufferIdle * TIME_FACTOR);
         printf("MAXAGE    : %lu milliseconds.\n", f32Parms.ulMaxAge * TIME_FACTOR);
         }

      printf("\n");
      ShowRASectors();
      printf("\n");
      printf("CACHE has space for %u sectors\n", f32Parms.usCacheSize);
      printf("CACHE contains %u sectors\n", f32Parms.usCacheUsed);
      printf("There are %u dirty sectors in cache.\n", f32Parms.usDirtySectors);
      if (f32Parms.usPendingFlush > 0)
         printf("%u sectors are in pending flush state.\n", f32Parms.usPendingFlush);
      printf("The cache hits ratio is %3d%%.\n",
         f32Parms.ulTotalHits * 100 / f32Parms.ulTotalReads);
      if (f32Parms.fUseShortNames)
         {
         printf("Internally, short names are used.\n");
         printf("All files are visible in DOS sessions.\n");
         }
      else
         {
         printf("Internally, long names are used.\n");
         printf("Files and directories with long names are hidden for DOS.\n");
         }
      printf("FAT32.IFS has currently %u GDT segments allocated.\n",
         f32Parms.usSegmentsAllocated);
      }

   return;
}