Needed this for the current toy, nothing exciting but seems to work OK. The test for the beginning of the buffer is probably redundant but you could just be lucky with some weird configuration that did not have a "\" in the return string from GetModuleFileNAme().
Change,
mov WORD PTR [eax+2], 0
To
mov WORD PTR [eax], 0
If you don't want the trailing backslash.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
uc_app_path proc
; ---------------------------------------------------
; return OFFSET of unicode app path with trailing "\"
; ---------------------------------------------------
LOCAL plen :DWORD
.data?
uc_path_buffer dw 260 dup (?)
.code
mov plen, rv(GetModuleFileNameW,NULL,OFFSET uc_path_buffer,260)
mov edx, OFFSET uc_path_buffer ; store beginning in EDX
mov eax, edx ; copy it to EAX
mov ecx, plen ; load path length into ECX
add ecx, ecx ; double it to convert unicode to byte length
add eax, ecx ; add length to OFFSET to get path end
; ------------------------------
; loop backwards to get last "\"
; ------------------------------
@@:
sub eax, 2
cmp WORD PTR [eax], "\" ; get last "\"
je @F
cmp eax, edx ; else exit at beginning if no "\"
jne @B
@@:
mov WORD PTR [eax+2], 0 ; terminate leaving trailing "\"
mov eax, OFFSET uc_path_buffer ; return the buffer OFFSET
ret
uc_app_path endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
23 instead of 34 bytes ;-)
mov edx, OFFSET uc_path_buffer ; store beginning in EDX
push edx
invoke GetModuleFileNameW, NULL, edx, 260
pop edx
lea eax, [edx+2*eax]
:bg
Plus the 520 byte buffer and the adjustment for trailing backslash or not, who cares. I left MS-DOS behind 15 years ago.