;**********************************************************************
;           Clipboard.asm (Thanks to Iczelion for corrections)
;   This program takes the command line argument (usually the path 
;   you want to record) and puts it on the clipboard
;   This is how it is used: put a shortcut to this prog in the 
;   windows 'Send to' folder.
;   If you need to stick a long path in some dialog edit, eg the
;   file open dialog, you could use the find in the start menu to 
;   locate your file, right click it and choose send to clipboard
;   (this program). then ctrl-V in your edit box and hey presto
;   the full path appears in the edit. (This is in short names format
;   so it can be used with the paste facility on the DOS in a window
;   C prompt.
;   An analysis of the program is as follows:
;   first, a call to GetCommandLine returns in eax the pointer to the
;   string containing the full command line including the full path of
;   this program (which we don't need.) If there are arguments (ie you
;   did drag something onto the icon rather than just clicking it to
;   start the prog), the string contains the unwanted bit in quotes
;   (ascii code 022h). However, if there are no arguments on the command
;   line, GetCommandLine returns the path of the program but NOT in
;   quotes. So we test the first byte pointed to by eax to see if it is
;   equal to ascii 022h. If it is,we increment eax
;   to lose the opening quotes and point edi here. we then put 022h
;   into al and do a repne scasb to get to the second quotes. There is
;   a space (ascii code 20h) following the second quotes so increment
;   edi to point to the first char of the path argument. Then we get the
;   length of the remainder of the string. Add one to the returned count
;   so we include the terminating zero (we need that when we set the
;   size of the GlobalAlloc next.) Then, we call or invoke OpenClipboard,
;   GlobalAlloc (as per Iczelion tutorial 12) and GlobalLock
;   Then we use the string function movsb to copy the string to the 
;   allocated memory.
;   So after the cleanup, there should be your subject path on
;   the clipboard
;   To test this prog just drag any file onto it in explorer and
;   start notepad and do a Ctrl-V to see what you've put on the Clip board
;**********************************************************************
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
    ;some error messages
nothing         db  "Nothing to put on clipboard",0
noopen          db  "Could not open clipboard",0
noalloc         db  "Unable to allocate memory",0
MsgCaption      db "Clipboard",0



.data?
hMemory HANDLE ?    ;handle to allocated memory
pMemory DWORD ?     ;pointer to allocated memory
len     DWORD ?     ;length of argument(path)
CmdLn   DWORD ?     ;pointer to our command line

.code
start:
      push edi
      push esi
      invoke GetCommandLine     ;pointer to command line string returned in eax
      cmp byte ptr[eax],22h
      jne noline
      inc eax                   ;remove the first speech bracket
      mov edi,eax               ;point edi to string
      mov al,22h                ;code for speech bracket
      or ecx,-01                ;put way enough on count register
      repne scasb               ;edi now points to second speech bracket
      inc edi
                    
      mov CmdLn,edi
      invoke    lstrlen,CmdLn
      .if eax==0
        jmp noline
      .endif
      
      inc eax                   ;to include the zero at the end of the string
      mov len,eax
      invoke    OpenClipboard,NULL
      .if eax==0
        jmp erroropen
      .endif
      invoke    GlobalAlloc,GMEM_MOVEABLE,len
      .if eax==0
        jmp  erroralloc
      .endif
      mov   hMemory,eax
      invoke    GlobalLock,hMemory
      mov   pMemory,eax
      mov esi,CmdLn             ;point source reg at the start of string
      mov edi,pMemory           ;and destination reg to allocated memory
      mov ecx,len               ; number of bytes to be copied
      rep movsb
      invoke EmptyClipboard
      invoke GlobalUnlock,hMemory
      invoke SetClipboardData,CF_TEXT,hMemory
      invoke CloseClipboard                     ;no GlobalFree
      jmp endit
noline:
      mov eax,offset nothing
      jmp mess
erroropen:
       mov eax,offset noopen
       jmp mess
erroralloc:
        mov eax,offset noalloc
mess:
        invoke MessageBox, NULL,eax, addr MsgCaption, MB_OK
endit:
        pop esi
        pop edi
        invoke ExitProcess,NULL

end start
