Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetShortPathName unpredictable results

GetShortPathName() is not working as I expect on XP SP3

http://msdn.microsoft.com/en-us/library/aa364989(VS.85).aspx

Is returning the input string for paths like:

C:\Test\LongFolderNameToTestWith\BinarySearch.ini

exactly as sent?

Yet:

C:\Documents and Settings\LocalService\NTUSER.DAT

Does make short names for the path, so I know I am calling the API correctly.

However:

C:\Documents and Settings\LocalService\BinarySearch.ini

Does not make a short name out of the filename, but does make short names for the path!?

Could someone help me understand this behavior and perhaps suggest a workaround.

Added:

I need to be able to make an 8.3 Path/filename to pass to a legacy app

How can this be done?

Added: SOLUTION

After MUCH reading/experimenting, it seems that the only reliable way to do this is using automation:

' ------------------------------------------------------------
' Library Name:      Microsoft Scripting Runtime 1.0
' Library File:      C:\WINDOWS\system32\scrrun.dll
' ------------------------------------------------------------
' Version Info:
' -------------
' Company Name:      Microsoft Corporation
' File Description:  Microsoft (R) Script Runtime
' File Version:      5.7.0.16599
' Internal Name:     scrrun.dll
' Legal Copyright:   Copyright (C) Microsoft Corp. 1996-2006, All Rights Reserved
' Original Filename: scrrun.dll
' Product Name:      Microsoft (R) Script Runtime
' Product Version:   5.7.0.16599
' ------------------------------------------------------------
' ProgID:            Scripting.FileSystemObject
' Interface Name:    ScriptingFileSystemObject
'
' Interface Prefix:  Scripting

This works.

A simple implementation in BASIC would be:

$PROGID_ScriptingFileSystemObject = "Scripting.FileSystemObject"

Interface Dispatch ScriptingFileSystemObject
    Member CALL GetFile  <&H0000271C>(IN FilePath   AS STRING<&H00000000>) AS ScriptingIFile
    Member CALL GetFolder<&H0000271D>(IN FolderPath AS STRING<&H00000000>) AS ScriptingIFolder 
END Interface

Interface Dispatch ScriptingFile
    Member GET ShortPath<&H000003EA>() AS STRING
    Member GET ShortName<&H000003E9>() AS STRING    
END Interface

Interface Dispatch ScriptingFolder
    Member GET ShortPath<&H000003EA>() AS STRING
    Member GET ShortName<&H000003E9>() AS STRING
END Interface


'-----------------------------------------------------------------------------      
FUNCTION FileShortPath( BYVAL sPathnFile AS STRING, sShort AS STRING ) AS LONG

  LOCAL vResult, vFilePath AS Variant

  LOCAL fso   AS ScriptingFileSystemObject
  LOCAL oFile AS ScriptingFile


    IF LEN(sPathnFile) = 0 THEN EXIT FUNCTION  ' Nothing sent

    SET fso   = NEW ScriptingFileSystemObject IN $PROGID_ScriptingFileSystemObject
    IF IsNothing(fso) THEN FUNCTION = -1 : EXIT FUNCTION

    SET oFile = NEW ScriptingFile             IN $PROGID_ScriptingFileSystemObject
    IF IsNothing(oFile) THEN FUNCTION = -2 : EXIT FUNCTION     


    vFilePath = sPathnFile 

    vResult = Empty
    OBJECT CALL fso.GetFile(vFilePath) TO vResult

    SET oFile = vResult 
    IF IsNothing(oFile) THEN FUNCTION = -3 : EXIT FUNCTION 

    vResult = Empty
    Object GET oFile.ShortName TO vResult
    sShort = VARIANT$(vResult) 

    vResult = Empty
    Object GET oFile.ShortPath TO vResult
    sShort = VARIANT$(vResult) 

    IF LEN(sShort) THEN FUNCTION = 1 ' Success

END FUNCTION

Thank you all for your suggestions.


I am still trying to find a way to reliably make an 8.3 Path/filename.

Is there any way to do this apart from using GETSHORTPATHNAME?

Solved. See above

It seems that MS has continued support for this for COM deciples only... why it is now unreliable in the C API remains a mystery.

like image 378
Mike Trader Avatar asked Dec 08 '22 07:12

Mike Trader


1 Answers

It is because the file name does not have an existing short name and XP SP3 is not automatically creating a short name for the file.

You can check this registry setting (if it exists) to see what it is currently set to.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation

When NtfsDisable8dot3NameCreation is set to 1 you will get the following behaviour:

If a folder/file already has a short name, for example "Program Files", then it will return the short name for that folder/file. But if a short name doesn't exist, you will instead get the long name for the file as it is the only name that exists for that object. If short names are disabled then there is no short name to get.

like image 180
Steven Avatar answered Dec 09 '22 19:12

Steven