Get Universal Name
From NSIS Wiki
Jump to navigationJump to search
Author: HotButteredSoul (talk, contrib) |
NSIS forum thread
Description
This is a function that, given any path, coverts it to a UNC path if necessary. This is especially useful when dealing with mapped network drives.
Function
I have not written a macro for this function.
Usage
Use the following code in your NSIS installer convert a mapped drive to a unc path:
Push "H:\path\file" Call get_universal_name Pop $0 ; = "\\servername\sharename\path\file"
Note: this function works fine with non-network paths. Thus, if you pass it "C:\somepath" it will return "C:\somepath". You don't have to check the type of drive before you call this function.
Code
# # GetUniversalName.nsh - by HotButteredSoul # # Function for getting the Universal name of a filepath. # # History: # *Unicode and 64bit support - Anders / 20131129 # *Initial version - HotButteredSoul / 20070216 !ifndef _GetUniversalName_nsh !define _GetUniversalName_nsh # # get_universal_name - gets universal name of a filepath # # Example: # # Push "H:\path\file" # Call get_universal_name # Pop $0 ; = "\\servername\sharename\path\file" # # Uses mpr.lib WNetGetUniversalNameA/W # # DWORD WNetGetUniversalName( # LPCTSTR lpLocalPath, // pointer to drive-based path for a network # // resource # DWORD dwInfoLevel, // specifies form of universal name to be # // obtained # LPVOID lpBuffer, // pointer to buffer that receives universal # // name data structure # LPDWORD lpBufferSize // pointer to variable that specifies size # // of buffer # ); # # Parameters # lpLocalPath # Points to a null-terminated string that is a drive-based path for a network resource. # For example, if drive H has been mapped to a network drive share, and the network # resource of interest is a file named SAMPLE.DOC in the directory \WIN32\EXAMPLES on # that share, the drive-based path is H:\WIN32\EXAMPLES\SAMPLE.DOC. # # dwInfoLevel # Specifies the type of data structure that the function will store in the buffer pointed # to by lpBuffer. This parameter can be one of the following values: Value Meaning # UNIVERSAL_NAME_INFO_LEVEL The function will store a UNIVERSAL_NAME_INFO data # structure in the buffer. (defined in WINNETWK.H as 1) # REMOTE_NAME_INFO_LEVEL The function will store a REMOTE_NAME_INFO data structure in # the buffer. (defined in WINNETWK.H as 2) # # The UNIVERSAL_NAME_INFO data structure points to a Universal Naming Convention (UNC) # name string. # # lpBuffer # Points to a buffer that receives the type of data structure specified by the # dwInfoLevel parameter. # # lpBufferSize # Points to a variable that specifies the size in bytes of the buffer pointed to by lpBuffer. # If the function succeeds, it sets the variable pointed to by lpBufferSize to the size # in bytes of the data structure stored in the buffer. If the function fails because the # buffer is too small, indicated by the ERROR_MORE_DATA error code, it sets the variable # pointed to by lpBufferSize to the required buffer size. # # Return Values # If the function succeeds, the return value is NO_ERROR (0). # # If the function fails, the return value is an error code. To get extended error # information, callGetLastError. GetLastError may return one of the following error codes: # # Value Meaning # ERROR_BAD_DEVICE The string pointed to by lpLocalPath is invalid (1200). # ERROR_CONNECTION_UNAVAIL There is no current connection to the remote device, but there # is a remembered (persistent) connection to it (1201). # ERROR_EXTENDED_ERROR A network-specific error occurred. Use the WNetGetLastError # function to obtain a description of the error (1208). # ERROR_MORE_DATA The buffer pointed to by lpBuffer is too small. The function sets the # variable pointed to by lpBufferSize to the required buffer size. More entries are # available with subsequent calls (234). # ERROR_NOT_SUPPORTED The dwInfoLevel parameter was set to UNIVERSAL_NAME_INFO_LEVEL, but # the network provider does not support UNC names. This function is not supported by # any of the network providers (282). # ERROR_NO_NET_OR_BAD_PATH None of the providers recognized this local name as having a # connection. However, the network is not available for at least one provider to whom # the connection may belong (1203). # ERROR_NO_NETWORK There is no network present (1222). # ERROR_NOT_CONNECTED The device specified by lpLocalPath is not redirected (2250). # Function get_universal_name Exch $0 ; local path (IN) Push $1 ; WNet error code Push $2 ; lpBuffer ; Allocate UNIVERSAL_NAME_INFO buffer (pointer and TCHAR array) !ifdef NSIS_PTR_SIZE & NSIS_CHAR_SIZE System::Call '*(p,&t${NSIS_MAX_STRLEN} "")p.r2' !define /math get_universal_name_UNISTRSIZE ${NSIS_CHAR_SIZE} * ${NSIS_MAX_STRLEN} !define /math get_universal_name_UNISIZE ${get_universal_name_UNISTRSIZE} + ${NSIS_PTR_SIZE} !undef get_universal_name_UNISTRSIZE System::Call 'mpr::WNetGetUniversalName(tr0,i1,p$2,*i${get_universal_name_UNISIZE})i.r1' !else System::Call '*(i,&t${NSIS_MAX_STRLEN} "")i.r2' !define /math get_universal_name_UNISIZE 4 + ${NSIS_MAX_STRLEN} System::Call 'mpr::WNetGetUniversalNameA(tr0,i1,i$2,*i${get_universal_name_UNISIZE})i.r1' !endif !undef get_universal_name_UNISIZE IntCmpU 0 $1 0 retlocal retlocal ; Local path is already in $0 and will be returned if the call failed System::Call "*$2(t.r0)" ; Extract universal string retlocal: System::Free $2 Pop $2 Pop $1 Exch $0 FunctionEnd !endif ; _GetUniversalName_nsh
Resources and Links
- NSIS forum thread
- System Plugin
API Functions used: