News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Mapi32 & GetProcAddress

Started by jj2007, November 02, 2014, 06:48:45 AM

Previous topic - Next topic

jj2007

I have a mapped drive on the network and need to know the drive letter.
ScLocalPathFromUNC should do the job, but I can't get it working.
- Masm32 mapilib assembles but the exe throws an error MsgBox saying entry point not found
- GetProcAddress "ScLocalPathFromUNC" fails miserably
- but (good news) ScLocalPathFromUNC@12 will be found by GetProcAddress

Only that it doesn't return a local drive name  :(

Any ideas? Any experience with this kind of problem? Google yields astonishingly little, although net use works fine. But I want to avoid launching a batch command 8)

Vortex

Quote- but (good news) ScLocalPathFromUNC@12 will be found by GetProcAddress

That's true :

\masm32\bin\dumpbin /EXPORTS C:\WINDOWS\system32\mapi32.dll | findstr ScLocalPathFromUNC

        193   94 000063CF ScLocalPathFromUNC@12


Here, they suggest to pass szUNC as UNICODE. The MSDN documentation does not mention about this.

Vortex

A quick sample based on the API NetShareGetInfo :

include     \masm32\include\masm32rt.inc

include     \masm32\include\netapi32.inc
includelib  \masm32\lib\netapi32.lib

SHARE_INFORMATION_502 equ 502

.data

_format     db '%ls',0

.data?

buffer      dd ?
ServerName  db 128 dup(?)
ShareName   db 128 dup(?)

.code

main PROC C uses esi argc:DWORD,argv:DWORD

    mov     eax,argc
    cmp     eax,3
    je      @f
    ret
@@:   

    mov     esi,argv

    mov     edx,DWORD PTR [esi+4]
    movzx   eax,BYTE PTR [edx]
    cmp     eax,'.'
    je      l1

    invoke  MultiByteToWideChar,CP_ACP,0,edx,\
            -1,ADDR ServerName,128           
l1:

    invoke  MultiByteToWideChar,CP_ACP,0,DWORD PTR [esi+8],\
            -1,ADDR ShareName,128

    invoke  NetShareGetInfo,ADDR ServerName,ADDR ShareName,\
            SHARE_INFORMATION_502,ADDR buffer

    test    eax,eax
    jz      @f
    ret
@@:
    mov     edx,buffer

    mov     eax,SHARE_INFO_502.shi502_path[edx]

    invoke  crt_printf,ADDR _format,eax

    invoke  NetApiBufferFree,buffer
    ret

main ENDP

END


H:\test shared as \\poseidon\sample :

net share | findstr sample
sample       H:\test

GetLocalPathFromUNC.exe poseidon sample
H:\test
GetLocalPathFromUNC.exe 192.168.1.2 sample
H:\test
GetLocalPathFromUNC.exe . sample
H:\test


The dot symbol is interpreted as the local computer name.

jj2007

#3
Thanks a lot, Erol - nice code :t

Quote from: Vortex on November 02, 2014, 08:59:49 AMthey suggest to pass szUNC as UNICODE. The MSDN documentation does not mention about this

I had tried that but no success.

Your code builds nicely but I get no results :(
With net use, the output is this:

Status       Local     Remote                    Network

-------------------------------------------------------------------------------
             J:        \\VBOXSVR\JShared         VirtualBox Shared Folders


What exactly does your exe expect as arguments? I tried some variants, but NetShareGetInfo always returns 2310...

P.S.: I rechecked my own attempt, and surprise surprise, without any changes it does now return the correct result ::)

include \masm32\MasmBasic\MasmBasic.inc      ; download
.data
LocPath      db MAX_PATH dup(?)
  Init
  Dll "Mapi32"
  Declare ScLocalPathFromUNC@12, 3
  Print Str$("Res=     \t%i\n", ScLocalPathFromUNC@12(wChr$("\\VBOXSVR\"), addr LocPath, MAX_PATH))
  Inkey "[", offset LocPath, "]"
  Exit
end start

Output: J:\


Note this requires an updated MasmBasic.inc (attached), as the old Declare macro stripped the decoration from ScLocalPathFromUNC@12 - not needed and not helpful in this case, although often stripping _somefunc@8 to somefunc seems necessary to make GetProcAddress work.

P.P.S.: It gets better and better :lol:

On further investigation, it turns out that ScLocalPathFromUNC@12 eventually (i.e. after difficult and lengthy negotiations whether MS Outlook or Mozilla Thunderbird should supply the necessary function...) uses GetFullPathName:

CPU Disasm
Address              Hex dump           Command                                      Comments
3604C3D3               50               push eax  ; pFileName
3604C3D4               57               push edi  ; pBuffer
3604C3D5               FF75 10          push dword ptr [ebp+10]  ; MAX_PATH
3604C3D8               56               push esi  ; pShortName
3604C3D9               FF15 F811F735    call near [<&KERNEL32.GetFullPathNameA>]

And WOW!, it returns J:\ to pBuffer. The point where it becomes hilarious, though, is that pShortName in my example contained a Unicode string - and it still worked! In fact, you can pass whatever you want, it always returns J:\ :bgrin:
Except when I launch it from the shared drive - in that case ScLocalPathFromUNC@12 returns bullshit, but (good news), GetFullPathNameA returns the local path when fed with a simple "\". If fed with the UNC path, though, it just returns the same UNC path. Microsoft at its best :t

MichaelW

Using the tools from a recent MinGW installation and two batch files I was able to create what I think is a workable import library for mapi32.dll, but to avoid having to add the decoration to ~170 exports I reduced the exports to just ScLocalPathFromUNC. The resulting import library links OK, but when I run the EXE I get a message box with "There is no email program associated to perform the requested action...", and when I close the message box the function returns 80004005h. I have no intention of installing an email program, so I did not bother with passing sensible parameters to the function.

Well Microsoft, here's another nice mess you've gotten us into.

jj2007

Thanks, Michael. I get the same error indeed, both with your and my own code, so the cause for the ScLocalPathFromUNC failure seems the absence of a mail program (which is in line with my observation during debugging above).

Conclusion: To get the drive letter, GetFullPathName("\", ..) is a far better choice.

Vortex

Hi Jochen,

Thanks for the GetFullPathNameA solution.

Sorry, I should be more specific concerning the usage of the application. Let's assume that you have folder name H:\test and it's shared under the name sample.

Computer name = poseidon

What's the local path of the share sample hosted by the computer named poseidon?

GetLocalPathFromUNC.exe poseidon sample
H:\test