Menu

#1298 FS COPY/QUERY requests can return RC 48 when a file exists

Win32
closed-fixed
5
2009-09-29
2009-09-21
No

On Windows, if you list the contents of C:\ directory (assuming that's the boot drive), you'll see files C:\PAGEFILE.SYS and C:\hiberfil.sys.

C:\>staf staf1f fs list directory C:\ EXT sys
Response
--------
CONFIG.SYS
hiberfil.sys
IO.SYS
MSDOS.SYS
pagefile.sys

Note that PAGEFILE.SYS and hiberfil.sys are system files that are continually in use (being updated by the operating system).

If you submit a FS QUERY ENTRY request on one of these files, or attempt to copy one of these files, it returns RC 48 (DoesNotExist) when the files do exist (as shown by the FS LIST DIRECTORY request). For example:

C:\>STAF staf1f FS QUERY ENTRY C:\PAGEFILE.SYS
Error submitting request, RC: 48
Additional info
---------------
Entry C:\PAGEFILE.SYS does not exist

C:\>STAF staf1f FS QUERY ENTRY C:\hiberfil.sys
Error submitting request, RC: 48
Additional info
---------------
Entry C:\hiberfil.sys does not exist

C:\>STAF staf1f FS COPY FILE C:\hiberfil.sys TOFILE C:\temp\hiberfile.tmp
Error submitting request, RC: 48
Additional info
---------------
File C:\hiberfil.sys does not exist

Since these files do exist, this is not the correct behavior.

Discussion

  • Sharon Lucas

    Sharon Lucas - 2009-09-29

    Also, fixed problems recognizing a Windows path name that is a root directory, like C:\, vs a relative directory like C:.

    Here's a cvs diff of the changes:

    Index: stafif/win32/STAFFileSystem.cpp

    RCS file: /cvsroot/staf/src/staf/stafif/win32/STAFFileSystem.cpp,v
    retrieving revision 1.27
    diff -r1.27 STAFFileSystem.cpp
    138,139c138,224
    < // Remove any trailing slashes (that are not also leading slashes) from a path
    < // and return the updated string.
    ---
    > static bool hasTrailingSlash(const STAFString &path)
    > {
    > unsigned int lastSlashLoc = path.findLastOf(
    > sBothSlash, STAFString::kChar);
    >
    > return ((lastSlashLoc + 1) == path.length());
    > }
    >
    >
    > // Check if a path is a root directory. Examples of root directories are:
    > // C:\ or C:/ or \\computername\c$\ or //computername/c$/
    >
    > static bool isRootDirectory(const STAFString &path)
    > {
    > STAFString newPath = path;
    >
    > if (newPath.findFirstNotOf(sBothSlash, STAFString::kChar) !=
    > STAFString::kNPos)
    > {
    > unsigned int lastNonSlashLoc =
    > newPath.findLastNotOf(sBothSlash, STAFString::kChar);
    >
    > if (lastNonSlashLoc + 1 != newPath.length())
    > {
    > newPath = newPath.subString(0, lastNonSlashLoc + 1,
    > STAFString::kChar);
    >
    > // We have to see if a root directory was specified
    > // C:\ or C:/ or \\computername\c$\ or //computername/c$
    > // If so, we need to add a trailing slash back to the end
    > // so that it doesn't become a relative path
    >
    > if ((newPath.length() == 2) &&
    > (newPath.subString(1, 1) == kUTF8_COLON))
    > {
    > return true;
    > }
    > else if (newPath.subString(0, 2, STAFString::kChar) == s2BackSlashes ||
    > newPath.subString(0, 2, STAFString::kChar) == s2Slashes)
    > {
    > // Check if the path starts with a share name using format:
    > // \\computername\sharename
    > // or
    > // //computername/sharename
    > // If so, we need to add a trailing slash back to the end
    > // so that it doesn't become a relative path
    >
    > unsigned int nextSlashPos = newPath.findFirstOf(
    > sBothSlash, 2, STAFString::kChar);
    >
    > if ((nextSlashPos != STAFString::kNPos) && (nextSlashPos >= 3))
    > {
    > // Has format \\...\ >
    > unsigned int startShareNamePos = newPath.findFirstNotOf(
    > sBothSlash, nextSlashPos + 1, STAFString::kChar);
    >
    > if (startShareNamePos != STAFString::kNPos)
    > {
    > unsigned int endShareNamePos = newPath.findFirstOf(
    > sBothSlash, startShareNamePos, STAFString::kChar);
    >
    > if (endShareNamePos == STAFString::kNPos)
    > {
    > // Has format \\...\...
    >
    > return true;
    > }
    > }
    > }
    > }
    > }
    > }
    >
    > return false;
    > }
    >
    >
    > // Remove any trailing slashes (that are not also leading slashes and are
    > // not trailing slashes for a root directory) from a path and return the
    > // updated string. For example:
    > // C:\\mydir\\ -> C:\\mydir
    > // C:/mydir/myfile.txt/ -> C:/mydir/myfile.txt
    > // Note the following are root directories so can't remove trailing slashes
    > // because then would become relative paths
    > // C:\ or C:/ -> C:\ > // \\computername\c$\ -> \\computername\c$\ 154a240,286
    >
    > // We have to see if a root directory was specified
    > // C:\ or C:/ or \\computername\c$\ or //computername/c$
    > // If so, we need to add a trailing slash back to the end
    > // so that it doesn't become a relative path
    >
    > if ((newPath.length() == 2) &&
    > (newPath.subString(1, 1) == kUTF8_COLON))
    > {
    > newPath += sBackSlash;
    > }
    > else if ((newPath.subString(0, 2, STAFString::kChar) ==
    > s2BackSlashes) ||
    > (newPath.subString(0, 2, STAFString::kChar) ==
    > s2Slashes))
    > {
    > // Check if the path starts with a share name using format:
    > // \\computername\sharename
    > // or
    > // //computername/sharename
    > // If so, we need to add a trailing slash back to the end
    > // so that it doesn't become a relative path
    >
    > unsigned int nextSlashPos = newPath.findFirstOf(
    > sBothSlash, 2, STAFString::kChar);
    >
    > if ((nextSlashPos != STAFString::kNPos) && (nextSlashPos >= 3))
    > {
    > // Has format \\...\ >
    > unsigned int startShareNamePos = newPath.findFirstNotOf(
    > sBothSlash, nextSlashPos + 1, STAFString::kChar);
    >
    > if (startShareNamePos != STAFString::kNPos)
    > {
    > unsigned int endShareNamePos = newPath.findFirstOf(
    > sBothSlash, startShareNamePos, STAFString::kChar);
    >
    > if (endShareNamePos == STAFString::kNPos)
    > {
    > // Has format \\...\...
    >
    > newPath += sBackSlash;
    > }
    > }
    > }
    > }
    168a301
    > // except for a root directory
    191d323
    < // cout << "GetFullPathName() failed for: " << orgPath << endl;
    194c326
    <
    ---
    >
    220d351
    < // cout << "GetLongPathName() failed for: " << path << endl;
    377c508
    < STAFString thePath(path);
    ---
    > STAFString orgPath(path);
    382c513
    < thePath = getFullLongPath(thePath);
    ---
    > STAFString thePath = getFullLongPath(orgPath);
    395a527,534
    >
    >
    > // If root directory, add trailing slash back to root
    >
    > if ((thePath.length() == 0) && hasTrailingSlash(orgPath))
    > {
    > theRoot += sBackSlash;
    > }
    433a573,579
    >
    > // If root directory, add trailing slash back to root
    >
    > if (hasTrailingSlash(orgPath))
    > {
    > theRoot += sBackSlash;
    > }
    487c633
    <
    ---
    >
    548,551d693
    < // Remove any trailing slashes (that are not also leading slashes)
    <
    < STAFString thePath = removeTrailingSlashes(path);
    <
    554,555c696,741
    < DWORD rc = GetFileAttributes(
    < thePath.toCurrentCodePage()->buffer());
    ---
    > // Get the full path and, if the path exists, convert the path to the
    > // long path name in the correct case
    >
    > STAFString thePath = getFullLongPath(STAFString(path));
    >
    > // We have to see if we have a path like <alpha>[\/]:
    > // If so, we can't call FindFirstFile() with a path like that.
    >
    > if ((thePath.length() != 2) || (thePath.subString(1,1) != kUTF8_COLON))
    > {
    > STAFString searchPath(thePath);
    >
    > if (isRootDirectory(thePath))
    > {
    > searchPath += sStar;
    > }
    >
    > // Try using FindFirstFile() to see if the path exists
    > //
    > // Note: GetFileAttributes() fails if the file is in use
    > // (e.g. C:\PAGEFILE.SYS), but FindFirstFile() doesn't fail.
    > // However, FindFirstFile() doesn't set the error code to
    > // ERROR_FILE_NOT_FOUND if specify a path that contains a
    > // directory that doesn't exist. That's why using both
    > // functions to determine if a path exists.
    >
    > WIN32_FIND_DATA data = { 0 };
    > HANDLE findHandle = FindFirstFile(
    > searchPath.toCurrentCodePage()->buffer(), &data);
    >
    > if (findHandle != INVALID_HANDLE_VALUE)
    > {
    > *exists = 1;
    > FindClose(findHandle);
    > return retCode;
    > }
    > else if (GetLastError() == ERROR_FILE_NOT_FOUND)
    > {
    > *exists = 0;
    > return retCode;
    > }
    > }
    >
    > // Try using GetFileAttributes() to see if the path exists
    >
    > DWORD rc = GetFileAttributes(thePath.toCurrentCodePage()->buffer());
    584,591c770,777
    < // We have to see if we have a path like <alpha>:[/\]. If so, we have
    < // to handle it specially, as Win32 doesn't like a call to
    < // FindFirstFile() with a path like that.
    < //
    < // Note: The number '7' was chosen to catch various weird possibilities
    < // such as "c:\\\\" without having to check every path.
    <
    < if (thePath.length() < 7)
    ---
    > // We have to see if we have a root directory path (e.g. C:\ or
    > // \\computername\C$\) or a path like C:
    > // If so, we have to handle it specially as Win32 doesn't like a
    > // call to FindFirstFile() with a path like that.
    >
    > if (isRootDirectory(thePath) ||
    > ((thePath.length() == 2) &&
    > (thePath.subString(1, 1) == kUTF8_COLON)))
    593,605c779,781
    < STAFFSPath tempPath(thePath);
    <
    < tempPath.setExtension(tempPath.extension());
    <
    < STAFString tempPathString(tempPath.asString());
    <
    < if ((tempPathString.length() == 2) &&
    < (tempPathString.subString(1, 1) == kUTF8_COLON))
    < {
    < *entry = new STAFFSEntryImpl(thePath, kSTAFFSDirectory, 0, 0,
    < STAFTimestamp::now().getImpl());
    < return kSTAFOk;
    < }
    ---
    > *entry = new STAFFSEntryImpl(thePath, kSTAFFSDirectory, 0, 0,
    > STAFTimestamp::now().getImpl());
    > return kSTAFOk;
    1191c1367,1375
    < STAFString theRootNameFilter(rootName + sBackSlash + sStar);
    ---
    >
    > // Remove the trailing slash from a root directory like C:\ >
    > if (hasTrailingSlash(theRootName))
    > {
    > theRootName = theRootName.subString(0, theRootName.length() - 1);
    > }
    >
    > STAFString theRootNameFilter(theRootName + sBackSlash + sStar);
    Index: stafproc/STAFFSService.cpp
    ===================================================================
    RCS file: /cvsroot/staf/src/staf/stafproc/STAFFSService.cpp,v
    retrieving revision 1.101
    diff -r1.101 STAFFSService.cpp
    1962c1962
    < // Remove trailing slashes, if any, in the file name
    ---
    > // Get the actual path name and remove any unnecessary trailing slashes
    3396c3396
    < // Remove trailing slashes, if any, in the file name
    ---
    > // Get the actual path name and remove any unnecessary trailing slashes
    3882,3884d3881
    <
    < // Remove trailing slashes, if any, in the file name
    < STAFString rootDir = dirPath.setRoot(dirPath.root()).asString();
    3944a3942,3962
    >
    > // Get the actual directory path name
    >
    > STAFString rootDir = dirPath.setRoot(dirPath.root()).asString();
    >
    > #ifdef STAF_OS_TYPE_WIN32
    >
    > // On Windows, need to remove the trailing backslash from a path that
    > // is a root directory like C:\ >
    > if (rootDir.findFirstNotOf(kUTF8_BSLASH) != STAFString::kNPos)
    > {
    > unsigned int lastNonSlashLoc = rootDir.findLastNotOf(kUTF8_BSLASH);
    >
    > if (lastNonSlashLoc + 1 != rootDir.length())
    > {
    > rootDir = rootDir.subString(
    > 0, lastNonSlashLoc + 1, STAFString::kChar);
    > }
    > }
    > #endif
    Index: stafproc/STAFProc.cpp
    ===================================================================
    RCS file: /cvsroot/staf/src/staf/stafproc/STAFProc.cpp,v
    retrieving revision 1.228
    diff -r1.228 STAFProc.cpp
    825c825
    < if (tmpPath.exists())
    ---
    > try
    827,843c827,846
    < STAFFSEntryPtr entry = tmpPath.getEntry();
    < STAFString namePattern(kUTF8_STAR);
    < STAFString extPattern(kUTF8_STAR);
    < unsigned int entryTypesUInt = kSTAFFSAll;
    < STAFFSCaseSensitive_t caseSensitive = kSTAFFSCaseDefault;
    < STAFString removeResult;
    <
    < STAFRC_t removeRC = removeDir(
    < entry, namePattern, extPattern, entryTypesUInt,
    < caseSensitive, removeResult);
    <
    < if (removeRC != kSTAFOk)
    < {
    < cout << "Error deleting temp directory: "
    < << tmpPath.asString()
    < << ", RC: " << removeRC << ", Result: "
    < << removeResult << endl;
    ---
    > if (tmpPath.exists())
    > {
    > STAFFSEntryPtr entry = tmpPath.getEntry();
    > STAFString namePattern(kUTF8_STAR);
    > STAFString extPattern(kUTF8_STAR);
    > unsigned int entryTypesUInt = kSTAFFSAll;
    > STAFFSCaseSensitive_t caseSensitive = kSTAFFSCaseDefault;
    > STAFString removeResult;
    >
    > STAFRC_t removeRC = removeDir(
    > entry, namePattern, extPattern, entryTypesUInt,
    > caseSensitive, removeResult);
    >
    > if (removeRC != kSTAFOk)
    > {
    > cout << "Error deleting temp directory: "
    > << tmpPath.asString()
    > << ", RC: " << removeRC << ", Result: "
    > << removeResult << endl;
    > }
    845d847
    < }
    847,851c849,862
    < try
    < {
    < // Don't want exceptions here
    < STAFFSEntryPtr tmpdir =
    < tmpPath.createDirectory(kSTAFFSCreatePath);
    ---
    > try
    > {
    > // Don't want exceptions here
    > STAFFSEntryPtr tmpdir =
    > tmpPath.createDirectory(kSTAFFSCreatePath);
    > }
    > catch (...)
    > { /* Do Nothing */ }
    >
    > if (!tmpPath.exists())
    > {
    > cout << "Error creating temp directory: "
    > << tmpPath.asString() << endl;
    > }
    854,856d864
    < { /* Do Nothing */ }
    <
    < if (!tmpPath.exists())
    858,859c866,867
    < cout << "Error creating temp directory: " << tmpPath.asString()
    < << endl;
    ---
    > cout << "Error checking existance of temp directory "
    > << tmpPath.asString() << endl;
    867,868c875,876
    <
    < if (!userPath.exists())
    ---
    >
    > try
    870,876d877
    < try
    < {
    < userPath.createDirectory(kSTAFFSCreatePath);
    < }
    < catch (...)
    < { /* Do Nothing */ }
    <
    879,880c880,891
    < cout << "Error creating user directory: "
    < << userPath.asString() << endl;
    ---
    > try
    > {
    > userPath.createDirectory(kSTAFFSCreatePath);
    > }
    > catch (...)
    > { /* Do Nothing */ }
    >
    > if (!userPath.exists())
    > {
    > cout << "Error creating user directory: "
    > << userPath.asString() << endl;
    > }
    882a894,898
    > catch (...)
    > {
    > cout << "Error checking existance of user directory "
    > << userPath.asString() << endl;
    > }
    1015,1016c1031
    < if (STAFFSPath(infFileName).exists() &&
    < !STAFFSPath(cmpFileName).exists())
    ---
    > try
    1018,1032c1033,1053
    < // Run the STAF Registration program by submitting a PROCESS START
    < // request and not waiting for it to complete (so that it runs a
    < // separate thread). This way, if a SHUTDOWN request is submitted
    < // before the STAFReg program is complete, then STAF can shut down
    < // without waiting for STAFReg to complete. Note that STAFReg can
    < // take 20 seconds or more to run if it fails to connect to the
    < // REGISTER service on the IBM internal registration machine due
    < // to machines that don't have access to the IBM internal
    < // registration machine because they are outside the IBM firewall,
    < // have BSO issues, or are on a isolated network, etc.)
    <
    < STAFResultPtr result = gSTAFProcHandlePtr->submit(
    < sLocal, sProcess,
    < "START COMMAND {STAF/Config/STAFRoot}/bin/STAFReg"
    < " SAMECONSOLE");
    ---
    > if (STAFFSPath(infFileName).exists() &&
    > !STAFFSPath(cmpFileName).exists())
    > {
    > // Run the STAF Registration program by submitting a PROCESS
    > // START request and not waiting for it to complete (so that
    > // it runs a separate thread). This way, if a SHUTDOWN
    > // request is submitted before the STAFReg program is
    > // complete, then STAF can shut down without waiting for
    > // STAFReg to complete. Note that STAFReg can take 20 seconds
    > // or more to run if it fails to connect to the REGISTER
    > // service on the IBM internal registration machine due to
    > // machines that don't have access to the IBM internal
    > // registration machine because they are outside the IBM
    > // firewall, have BSO issues, or are on a isolated network,
    > // etc.)
    >
    > STAFResultPtr result = gSTAFProcHandlePtr->submit(
    > sLocal, sProcess,
    > "START COMMAND {STAF/Config/STAFRoot}/bin/STAFReg"
    > " SAMECONSOLE");
    > }
    1033a1055,1056
    > catch (...)
    > { /* Do Nothing */}
    2613c2636,2651
    < unsigned int theDirectoryExists = toDirPath.exists();
    ---
    > unsigned int theDirectoryExists = 0;
    >
    > try
    > {
    > theDirectoryExists = toDirPath.exists();
    > }
    > catch (STAFBaseOSErrorException &sboe)
    > {
    > STAFString errMsg = "Error checking if TODIRECTORY '" +
    > toDirectory + "' exists\n" +
    > sboe.getText() + STAFString(": ") + sboe.getErrorCode();
    > connection->writeUInt(kSTAFBaseOSError);
    > connection->writeString(errMsg);
    >
    > return;
    > }
    3271a3310
    > unsigned int theFileExists = 0;
    3273c3312,3325
    < unsigned int theFileExists = toPath.exists();
    ---
    > try
    > {
    > theFileExists = toPath.exists();
    > }
    > catch (STAFBaseOSErrorException &sboe)
    > {
    > STAFString errMsg = "Error checking if to file '" +
    > toFile + "' exists\n" +
    > sboe.getText() + STAFString(": ") + sboe.getErrorCode();
    > connection->writeUInt(kSTAFBaseOSError);
    > connection->writeString(errMsg);
    >
    > return;
    > }
    Index: test/STAFTest.xml
    ===================================================================
    RCS file: /cvsroot/staf/src/staf/test/STAFTest.xml,v
    retrieving revision 1.279
    diff -r1.279 STAFTest.xml
    7c7
    < Description: This STAX xml job tests STAF V3.3.4 and STAX V3.3.7
    ---
    > Description: This STAX xml job tests STAF V3.3.5 and STAX V3.3.8
    2930a2931,2972
    > <!-- On Windows, test that if "FS LIST DIRECTORY C:\ NAME pagefile EXT sys TYPE F"
    > includes a file named pagefile.sys, that a FS QUERY ENTRY C:\pagefile.sys request
    > successfully returns 0 -->
    >
    > <if expr="TestMachOSType.find('Win') == 0">
    > <sequence>
    >
    > <script>request = 'LIST DIRECTORY {STAF/Config/BootDrive}\ NAME pagefile EXT sys TYPE F'</script>
    > <message>'Testing machine: %s service: FS request: %s' % (TestMach, request)</message>
    >
    > <stafcmd>
    > <location>TestMach</location>
    > <service>'FS'</service>
    > <request>request</request>
    > </stafcmd>
    >
    > <if expr="RC == STAFRC.Ok and len(STAFResult) == 1">
    > <sequence>
    >
    > <script>request = 'QUERY ENTRY {STAF/Config/BootDrive}\pagefile.sys'</script>
    > <message>'Testing machine: %s service: FS request: %s' % (TestMach, request)</message>
    >
    > <stafcmd>
    > <location>TestMach</location>
    > <service>'FS'</service>
    > <request>request</request>
    > </stafcmd>
    >
    > <call function="'STAXUtilCheckSuccess'">
    > { 'result': RC == STAFRC.Ok,
    > 'failMsg': 'STAF %s FS %s failed. RC=%s Result=%s' % \ > (TestMach, request, RC, STAFResult),
    > 'sendToMonitor': 1,
    > 'recordStatus': 1 }
    > </call>
    >
    > </sequence>
    > </if>
    >
    > </sequence>
    > </if>
    >

     
  • Sharon Lucas

    Sharon Lucas - 2009-09-29
    • status: open --> closed-fixed
     

Log in to post a comment.