News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Getting a "DIR"

Started by Jimg, June 04, 2008, 07:14:56 PM

Previous topic - Next topic

Jimg

And back to the original question, if I'm going to use masmlib anyway, this works for me-

.data
  cmd2 db 'cmd /c dir "C:\help new\*.htm" /s/w/b/a-d > '
  dest db "C:allhtm.txt",0
.code
    invoke wshell,addr cmd2

can't get much simpler than that.

Vortex

The GeneSys project provides a shell function :

    .486                      ; create 32 bit code
    .model flat, stdcall      ; 32 bit memory model
    option casemap :none      ; case sensitive

    include \GeneSys\include\windows.inc
    include \GeneSys\include\kernel32.inc

    .code

;----------------------------------------------------------------------------;
; This is a translation of a shell script originally written by Edgar Hansen ;
; in GoASM code. Translation by Paul E. Brennick  <pebrennick@verizon.net>   ;
;                                                                            ;
; Shell:      This function will run an executable and wait until it has     ;
;             finished before continuing. The function provides for a time   ;
;             out for a maximum wait period.                                 ;
; Parameters: lpfilename = The fully qualified path to an executable to run  ;
;             dwTimeOut = The amount of time in milliseconds to wait, -1 for ;
;             no timeout                                                     ;
; Returns:    0 if successful, STATUS_TIMEOUT if the timeout has elapsed     ;
;             -1 if there was an error creating the process                  ;
;                                                                            ;
;----------------------------------------------------------------------------;
Shell PROC lpfilename:DWORD, dwTimeOut:DWORD
    LOCAL   Sh_st_info :STARTUPINFO
    LOCAL   Sh_pr_info :PROCESS_INFORMATION

    mov     DWORD PTR [Sh_st_info.cb], SIZEOF STARTUPINFO
    invoke  GetStartupInfoA, ADDR Sh_st_info
    mov     DWORD PTR [Sh_st_info.lpReserved], 0
    invoke  CreateProcessA, 0, [lpfilename], 0, 0, 0, 0, 0, 0, \
            ADDR Sh_st_info, ADDR Sh_pr_info
    test    eax, eax
    jz ERROR
    invoke  WaitForSingleObject, [Sh_pr_info.hProcess], [dwTimeOut]
    push    eax
    invoke  CloseHandle, [Sh_pr_info.hThread]
    invoke  CloseHandle, [Sh_pr_info.hProcess]
    pop     eax
    test    eax, eax
    RET
ERROR:
    xor     eax, eax
    sub     eax, 1
    RET
Shell ENDP

    end

jj2007

Looks good, Vortex. Main difference to my version is that you call GetStartupInfo (which in turn allows to declare the STARTUPINFO locally). How much is the added value? MSDN has some pretty original remarks on this function:

This function does not return a value. (if you find one, throw it away!)

If an error occurs, the ANSI version of this function (GetStartupInfoA) can raise an exception (but we won't tell you when, haha!). The Unicode version (GetStartupInfoW) does not fail. (never! promised!)

sinsi

For all that code to shell out to a cmd prompt, why not this code

allspec dd '*'
updir   dd '..'

search_dir proc uses ebx esi
local wfd:WIN32_FIND_DATA
lea esi,wfd
invoke FindFirstFile,offset allspec,esi
cmp eax,-1
jz done
mov ebx,eax
  next: call found
        test wfd.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
jz over
        cmp wfd.cFileName,'.'
        jz over
invoke SetCurrentDirectory,addr wfd.cFileName
test eax,eax
jz fini
call search_dir
invoke SetCurrentDirectory,offset updir
  over:
invoke FindNextFile,ebx,esi
test eax,eax
jnz next
  fini: invoke FindClose,ebx
  done: ret
search_dir endp

The only other code needed is the 'found' proc called (oh, and some error checking)
Light travels faster than sound, that's why some people seem bright until you hear them.

hutch--

I am inclided to agree with sinsi here, for the amount of code to shell out to CMD.EXE or command.com, you may as well get the data yourself.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

#20
Here is a version that returns success in eax plus the exit code in ecx. It seems the topic has moved to "what is the best version of SHELL" ;-)

include \masm32\include\masm32rt.inc

ShellWait PROTO: DWORD, :SDWORD

.code

PathAndCmd db "C:\WINDOWS\notepad.exe C:\WINDOWS\SYSTEM.INI", 0
AppName  db "ExecWait:", 0

start: invoke ShellWait, addr PathAndCmd, 0 ; try 2000 as timeout
.if eax
invoke MessageBox, 0, str$(ecx), chr$("We are done with this exit code:"), MB_OK
  .else
invoke MessageBox, 0, addr PathAndCmd, chr$("Something went wrong:"), MB_OK
.endif
invoke ExitProcess, 0

ShellWait proc cmdline:DWORD, timeout:SDWORD
LOCAL ExCode:DWORD ; exit code, returned in ecx
LOCAL sinfo:STARTUPINFO
LOCAL pinfo:PROCESS_INFORMATION
  mov sinfo.cb, sizeof sinfo ; Windows needs to know the STARTUPINFO version
  mov sinfo.dwFlags, STARTF_USESHOWWINDOW ; these two are
  mov sinfo.wShowWindow, SW_MAXIMIZE ; optional but useful
  invoke GetStartupInfo, addr sinfo ; fill the structure
  xor ecx, ecx ; using ecx as NULL saves some bytes
  mov ExCode, ecx ; valid only if eax!=0
  invoke CreateProcess, ecx, ; no pathname
  cmdline, ; the only bit that REALLY counts...!
  ecx, ecx, ecx, ; lpProcessAttributes, lpThreadAttributes, bInheritHandles
  ecx, ecx, ecx, ; xx_PRIORITY_CLASS, lpEnvironment, lpCurrentDirectory
  addr sinfo, addr pinfo
  mov eax, pinfo.hProcess
  .if eax
push eax
.if timeout<=0 ; for those lazybones who don't want to type INFINITE
mov timeout, INFINITE ; -1
.endif
invoke WaitForSingleObject, eax, timeout ; specify milliseconds here
invoke GetExitCodeProcess, pinfo.hProcess, addr ExCode
invoke CloseHandle, pinfo.hProcess
invoke CloseHandle, pinfo.hThread
pop eax ; hProcess
  .endif
  mov ecx, ExCode
  ret
ShellWait endp   ; <-- Edit
end start



jj2007

  mov sinfo.dwFlags, STARTF_USESHOWWINDOW    ; these two are
  mov sinfo.wShowWindow, SW_MAXIMIZE          ; optional but useful


I could swear these flags worked on my office puter with XP SP2. But now it's weekend, and on XP SP1 the flags are being happily ignored by Notepad. When started from a Desktop shortcut, they work, though. Windows mysteries...

jj2007

#22
Quote from: jj2007 on June 07, 2008, 12:03:35 AM
  mov sinfo.dwFlags, STARTF_USESHOWWINDOW    ; these two are
  mov sinfo.wShowWindow, SW_MAXIMIZE          ; optional but useful


I could swear these flags worked on my office puter with XP SP2. But now it's weekend, and on XP SP1 the flags are being happily ignored by Notepad. When started from a Desktop shortcut, they work, though. Windows mysteries...

No Windows mysteries: jj lacked sleep.

Old:
LOCAL pinfo:PROCESS_INFORMATION
  mov sinfo.cb, sizeof sinfo ; Windows needs to know the STARTUPINFO version
  mov sinfo.dwFlags, STARTF_USESHOWWINDOW ; these two are
  mov sinfo.wShowWindow, SW_MAXIMIZE ; optional but useful
  invoke GetStartupInfo, addr sinfo ; fill the structure

New:
LOCAL pinfo:PROCESS_INFORMATION
  invoke GetStartupInfo, addr sinfo ; fill the structure, then change the two members:
  ; NO mov sinfo.cb, sizeof sinfo ; Windows hopefully knows the STARTUPINFO version
  mov sinfo.dwFlags, STARTF_USESHOWWINDOW ; these two are
  mov sinfo.wShowWindow, SW_MAXIMIZE ; optional but useful

After all, I found "invoke ShellWait, addr PathAndCmd, 0" far too clumsy, so I added a macro, see attachment. Usage:

.data
PathAndCmd   db "C:\WINDOWS\notepad.exe C:\WINDOWS\SYSTEM.INI", 0

.code
start:
   Launch PathAndCmd      ; plain launch
   Launch PathAndCmd, SW_MAXIMIZE      ; gimme a full screen
   Launch PathAndCmd, SW_HIDE, 2000      ; do it hidden, and come back soon


[attachment deleted by admin]

Jimg

The simplest, laziest way is wshell-

.data
  cmd2 db 'cmd /c dir "C:\help new\*.htm" /s/w/b/a-d > ' ; or whatever options you want
  dest db "C:allhtm.txt",0
.code
    invoke wshell,addr cmd2



jj2007

Quote from: Jimg on December 28, 2010, 03:33:58 PM
The simplest, laziest way is wshell-

Jim,
You realise this thread is a bit old, do you? :wink
But it works indeed. The strange thing is that MSDN is denying the existence of wshell...