Get Universal Name: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
(Getting the UNC path from a Mapped Network Drive) |
(Include sizeof(UNIVERSAL_NAME_INFO.lpUniversalName) in the buffer size we report) |
||
(3 intermediate revisions by 3 users not shown) | |||
Line 9: | Line 9: | ||
I have not written a macro for this function. | I have not written a macro for this function. | ||
=== Usage === | === Usage === | ||
Use the following code in your NSIS installer to | Use the following code in your NSIS installer convert a mapped drive to a unc path: | ||
<highlight-nsis> | <highlight-nsis> | ||
Push "H:\path\file" | Push "H:\path\file" | ||
Line 15: | Line 15: | ||
Pop $0 ; = "\\servername\sharename\path\file" | Pop $0 ; = "\\servername\sharename\path\file" | ||
</highlight-nsis> | </highlight-nsis> | ||
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 === | === Code === | ||
Line 23: | Line 25: | ||
# Function for getting the Universal name of a filepath. | # Function for getting the Universal name of a filepath. | ||
# | # | ||
# History: | |||
# *Unicode and 64bit support - Anders / 20131129 | |||
# *Initial version - HotButteredSoul / 20070216 | |||
!ifndef _GetUniversalName_nsh | !ifndef _GetUniversalName_nsh | ||
Line 36: | Line 41: | ||
# Pop $0 ; = "\\servername\sharename\path\file" | # Pop $0 ; = "\\servername\sharename\path\file" | ||
# | # | ||
# Uses mpr.lib WNetGetUniversalNameA | # Uses mpr.lib WNetGetUniversalNameA/W | ||
# | # | ||
# DWORD WNetGetUniversalName( | # DWORD WNetGetUniversalName( | ||
Line 103: | Line 108: | ||
# | # | ||
Function get_universal_name | Function get_universal_name | ||
Exch $0 ; local path (IN) | Exch $0 ; local path (IN) | ||
Push $1 ; | Push $1 ; WNet error code | ||
Push $2 ; lpBuffer | 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 | 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 | System::Free $2 | ||
Pop $2 | Pop $2 | ||
Pop $1 | |||
Pop $ | Exch $0 | ||
Exch $ | |||
FunctionEnd | FunctionEnd | ||
!endif ; _GetUniversalName_nsh | !endif ; _GetUniversalName_nsh | ||
</highlight-nsis> | </highlight-nsis> | ||
== Resources and Links == | == Resources and Links == |
Latest revision as of 20:54, 29 November 2013
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: