The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Magnum on March 26, 2011, 05:57:17 PM

Title: Activated only with drive G:
Post by: Magnum on March 26, 2011, 05:57:17 PM
This works fine when my thumb drive is plugged in, but unfortunately it
is also activated when I turn on my printer or insert a CD or DVD.

I need it to only work for drive G:.


include \masm32\include\masm32rt.inc

CTEXT macro Text
   local szText
   .data
   szText byte Text, 0
   .code
   exitm <offset szText>  
endm


DBT_DEVICEARRIVAL        equ 8000h
DBT_DEVICEREMOVECOMPLETE equ 8004h


.data

No_Batch_File  db      "Batch file is not present.",0
Batch_File     db      "C:\Bat\BAK_ALL.bat",0
AppName        db      "UsbToHD",0

szClassName BYTE "USB_Watcher", 0

.data?

StartupInfo        STARTUPINFO         <?>
szComspec        db MAX_PATH dup(?)
szAppname        db MAX_PATH dup(?)
ProcessInfo        PROCESS_INFORMATION <?>

hInst DWORD ?
hMain DWORD ?
wc WNDCLASSEX <?>
msg MSG <?>

.code

USBWatcher:

invoke GetModuleHandle, NULL
mov hInst, eax

mov wc.hInstance, eax
mov wc.lpszClassName, offset szClassName
mov wc.lpfnWndProc, offset WndProc
mov wc.style, CS_DBLCLKS
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.hIcon, NULL
mov wc.hIconSm, NULL
mov wc.hCursor, NULL
mov wc.lpszMenuName, NULL
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
mov wc.hbrBackground, NULL
invoke RegisterClassEx, addr wc

invoke CreateWindowEx,
NULL, \ ; don't need this
offset szClassName, \
NULL, \
NULL, \ ; don't need a window style
0, 0, 0, 0, \ ; don't need top, left, width or height
NULL, \ ; message only window
NULL, \
hInst, \
NULL
mov hMain, eax

.while TRUE
invoke GetMessage,addr msg,NULL,0,0
 .break .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
invoke ExitProcess, 0

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

  .if uMsg==WM_DEVICECHANGE
  .if wParam == DBT_DEVICEARRIVAL
;invoke MessageBox, NULL, offset szMsgConnected, offset szClassName, MB_OK or MB_ICONINFORMATION

  ; Check if batch file is present
invoke GetFileAttributes,offset Batch_File

.IF EAX == 0FFFFFFFFh
  invoke MessageBox, 0, ADDR No_Batch_File, ADDR AppName,MB_ICONINFORMATION
  invoke  ExitProcess,NULL
.ENDIF

     invoke GetStartupInfo, addr StartupInfo
invoke GetEnvironmentVariable, CTEXT('ComSpec'), addr szComspec, sizeof szComspec
invoke wsprintf, addr szAppname, CTEXT('"%s" /c "C:\Bat\BAK_ALL.bat"'), addr szComspec
invoke CreateProcess, 0, addr szAppname, 0, 0, FALSE, \
NORMAL_PRIORITY_CLASS, 0, 0, addr StartupInfo, addr ProcessInfo

     invoke WaitForSingleObject, ProcessInfo.hProcess, INFINITE

           .elseif wParam == DBT_DEVICEREMOVECOMPLETE
;invoke MessageBox, hWnd, offset szMsgDisCon, offset szClassName, MB_OK or MB_ICONINFORMATION
;invoke SendMessage, hWnd, WM_CLOSE, NULL, NULL

.endif
.elseif uMsg==WM_CLOSE
;invoke MessageBox, NULL, offset szMsgClose, offset szClassName, MB_OK or MB_ICONINFORMATION
;invoke PostQuitMessage, 0
ret
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret

.endif
xor eax, eax
ret
WndProc endp


Title: Re: Activated only with drive G:
Post by: oex on March 26, 2011, 06:12:27 PM
Check for drive G

GetLogicalDrives
Title: Re: Activated only with drive G:
Post by: baltoro on March 26, 2011, 06:18:19 PM
I remember running into a user-mode sample application (the source code was from the DDK) that did something similar. It was called: USB View.
From the documentation: Usbview.exe is a Windows GUI application that allows you to browse all USB controllers and connected USB devices on your system.
The source code is in C. In that example, all the device controllers were enumerated, and information retrieved using repeated calls to: DeviceIoControl (http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx).
It's obviously alot more intensive than what you need here; and, USB View does not enumerate devices on pre-Windows XP SP1-based computers.
Title: Re: Activated only with drive G:
Post by: qWord on March 26, 2011, 06:34:55 PM
look for lParam: it is an pointer to an struct containgin information about the device -> DBT_DEVICEARRIVAL Event (http://msdn.microsoft.com/en-us/library/aa363205(v=vs.85).aspx)
Title: Re: Activated only with drive G:
Post by: oex on March 26, 2011, 07:18:35 PM
Quote from: qWord on March 26, 2011, 06:34:55 PM
look for lParam: it is an pointer to an struct containgin information about the device -> DBT_DEVICEARRIVAL Event (http://msdn.microsoft.com/en-us/library/aa363205(v=vs.85).aspx)

Out of interest did this not work?
http://www.masm32.com/board/index.php?topic=13899.msg109904#msg109904

I remember I had some problem recognising my MP3 player.... It has storage but did not register as a volume or somesuch....
Title: Re: Activated only with drive G:
Post by: Magnum on March 26, 2011, 07:20:59 PM
This will work if I can figure out how to test if bit 6 has been set.

I looked at the info for test and some old code, but could not find what I was looking for.


CheckDriveC proc    uses ebx esi edi ebp    DriveList: DWORD
            mov     eax, DriveList
            and     eax, 4          ; if bit #2 is set -> C is available
            shr     eax,2               ; bit 6 is G:
Title: Re: Activated only with drive G:
Post by: oex on March 26, 2011, 07:21:24 PM
Quote from: Magnum on March 26, 2011, 07:20:59 PM
This will work if I can figure out how to test if bit 6 has been set.

I looked at the info for test and some old code, but could not find what I was looking for.


CheckDriveC proc    uses ebx esi edi ebp    DriveList: DWORD
            mov     eax, DriveList
            and     eax, 4          ; if bit #2 is set -> C is available
            shr     eax,2               ; bit 6 is G:


bt instruction
Title: Re: Activated only with drive G:
Post by: Magnum on March 26, 2011, 08:18:59 PM
Getting "Cannot nest procedures."

Code works, maybe I messed up some .if statement.


; Usb_Watcher.asm
;
include \masm32\include\masm32rt.inc

CheckDriveC proto :DWORD

CTEXT macro Text
    local szText
    .data
    szText byte Text, 0
    .code
    exitm <offset szText>   
endm


DBT_DEVICEARRIVAL        equ 8000h
DBT_DEVICEREMOVECOMPLETE equ 8004h


.data

No_Batch_File  db      "Batch file is not present.",0
Batch_File     db      "C:\Bat\BAK_ALL.bat",0
AppName        db      "UsbToHD",0

szClassName BYTE "USB_Watcher", 0

.data?

StartupInfo         STARTUPINFO         <?>
szComspec         db MAX_PATH dup(?)
szAppname         db MAX_PATH dup(?)
ProcessInfo         PROCESS_INFORMATION <?>

hInst DWORD ?
hMain DWORD ?
wc WNDCLASSEX <?>
msg MSG <?>

.code

USBWatcher:

invoke GetModuleHandle, NULL
mov hInst, eax

mov wc.hInstance, eax
mov wc.lpszClassName, offset szClassName
mov wc.lpfnWndProc, offset WndProc
mov wc.style, CS_DBLCLKS
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.hIcon, NULL
mov wc.hIconSm, NULL
mov wc.hCursor, NULL
mov wc.lpszMenuName, NULL
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
mov wc.hbrBackground, NULL
invoke RegisterClassEx, addr wc

invoke CreateWindowEx,
NULL, \ ; don't need this
offset szClassName, \
NULL, \
NULL, \ ; don't need a window style
0, 0, 0, 0, \ ; don't need top, left, width or height
NULL, \ ; message only window
NULL, \
hInst, \
NULL
mov hMain, eax

.while TRUE
invoke GetMessage,addr msg,NULL,0,0
  .break .if !eax
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
invoke ExitProcess, 0

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

  .if uMsg==WM_DEVICECHANGE
  .if wParam == DBT_DEVICEARRIVAL

   ; Check if batch file is present
invoke GetFileAttributes,offset Batch_File

.IF EAX == 0FFFFFFFFh
   invoke MessageBox, 0, ADDR No_Batch_File, ADDR AppName,MB_ICONINFORMATION
   invoke  ExitProcess,NULL
.ENDIF

invoke  GetLogicalDrives        ; get drives
invoke  CheckDriveC, eax        ; check if drive G: is available

CheckDriveC proc    uses ebx esi edi ebp    DriveList: DWORD

            mov   eax, DriveList
            bt eax, 6 ; check if bit 6 is set (Drive G:)
            ret
           
CheckDriveC endp

        .if     (eax == 7Ch)
               
                jmp continue
        .else

        invoke  ExitProcess, 0
       
        .endif

continue:

      invoke GetStartupInfo, addr StartupInfo
invoke GetEnvironmentVariable, CTEXT('ComSpec'), addr szComspec, sizeof szComspec
invoke wsprintf, addr szAppname, CTEXT('"%s" /c "C:\Bat\BAK_ALL.bat"'), addr szComspec
invoke CreateProcess, 0, addr szAppname, 0, 0, FALSE, \
NORMAL_PRIORITY_CLASS, 0, 0, addr StartupInfo, addr ProcessInfo

      invoke WaitForSingleObject, ProcessInfo.hProcess, INFINITE

            .elseif wParam == DBT_DEVICEREMOVECOMPLETE


.endif
.elseif uMsg==WM_CLOSE

ret
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret

.endif
xor eax, eax
ret
WndProc endp

end USBWatcher
Title: Re: Activated only with drive G:
Post by: oex on March 26, 2011, 08:20:50 PM
You need to put:

CheckDriveC proc    uses ebx esi edi ebp    DriveList: DWORD

            mov   eax, DriveList
            bt   eax, 6 ; check if bit 6 is set (Drive G:)
            ret
           
CheckDriveC endp

outside the WndProc PROC
Title: Re: Activated only with drive G:
Post by: Magnum on March 26, 2011, 09:49:05 PM
I have to check more drives because drive letter depends on whether printer is turned on.

I got C:\masm32\SOURCE\Usb_Watcher.asm(111) : error A2170: directive must appear inside a macro


invoke  GetLogicalDrives        ; get drives
invoke  CheckDriveG, eax        ; check if drive G: is available

        push eax ; save for later use

        .if     (eax == 7Ch)

           ; check if G:drive has a Backup directory
           ; G: may be the printer drive
           
           invoke GetFileAttributes,offset G_USB_Directory

        .IF (EAX == 0FFFFFFFFh)

          goto check_4_H_Drive 

        .ENDIF

        .endif

check_4_H_Drive: ; bit 7 is H: drive

         pop eax

         .if (eax == 0F8h)   

         invoke GetFileAttributes,offset H_USB_Directory

        .IF (EAX == 0FFFFFFFFh)

        invoke  ExitProcess, 0
       
        .endif
        .endif

continue:

      invoke GetStartupInfo, addr StartupInfo
invoke GetEnvironmentVariable, CTEXT('ComSpec'), addr szComspec, sizeof szComspec
invoke wsprintf, addr szAppname, CTEXT('"%s" /c "C:\Bat\BAK_ALL.bat"'), addr szComspec
invoke CreateProcess, 0, addr szAppname, 0, 0, FALSE, \
NORMAL_PRIORITY_CLASS, 0, 0, addr StartupInfo, addr ProcessInfo

      invoke WaitForSingleObject, ProcessInfo.hProcess, INFINITE

            .elseif wParam == DBT_DEVICEREMOVECOMPLETE


.endif
.elseif uMsg==WM_CLOSE

ret
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret

.endif
xor eax, eax
ret
WndProc endp

CheckDriveG proc    uses ebx esi edi ebp    DriveList: DWORD

            mov   eax, DriveList
            bt eax, 6 ; check if bit 6 is set (Drive G:)
            ret
           
CheckDriveG endp

CheckDriveH proc    uses ebx esi edi ebp    DriveList: DWORD

            mov   eax, DriveList
            bt eax, 7 ; check if bit 7 is set (Drive H:)
            ret
           
CheckDriveH endp

end USBWatcher

Title: Re: Activated only with drive G:
Post by: jj2007 on March 26, 2011, 10:30:35 PM
Even MasmBasic has no GOTO, Andy ;-)
Title: Re: Activated only with drive G:
Post by: ragdog on March 26, 2011, 10:53:04 PM
Hi Andy

I have your send already a source for detect a usb drive oder if disconnect

Detect USB device insertion:
http://www.winasm.net/forum/index.php?showtopic=3472
Title: Re: Activated only with drive G:
Post by: Magnum on March 26, 2011, 11:10:30 PM
Yes, but I have to modify it for a new situation.

Title: Re: Activated only with drive G:
Post by: Magnum on March 26, 2011, 11:12:15 PM
Ollydbg will load this, but won't run it.

I need to see if my code is properly detecting whether a drive has as a  "backup" directory.


invoke  GetLogicalDrives        ; get drives
invoke  CheckDriveG, eax        ; check if drive G: is available

        push eax ; save for later use

        .if     (eax == 7Ch) ;match3

           ; check if G:drive has a Backup directory
           ; G: may be the printer drive
           
           invoke GetFileAttributes,offset G_USB_Directory

        .IF (EAX == 0FFFFFFFFh) ;match4

          jmp check_4_H_Drive 

        .ENDIF                  ;match3 
                 
        .endif                  ;match4

check_4_H_Drive: ; bit 7 is H: drive

         pop eax

         .if (eax == 0F8h)   

         invoke GetFileAttributes,offset H_USB_Directory
         
        .IF (EAX == 0FFFFFFFFh)

        int 3

        invoke  ExitProcess, 0

        .endif
        .endif
continue:

Title: Re: Activated only with drive G:
Post by: oex on March 27, 2011, 12:42:07 AM
bsf eax, [ebx].dbcv_unitmask
add eax, 65
mov esi, chr$("X:\backup\.")
mov [esi], al
invoke exist, esi

There is a slight error in this.... "Although the dbcv_unitmask member may specify more than one volume in any message".... I *think* this means a partitioned drive....

It also says "this does not guarantee that only one message is generated for a specified event".... ie I guess this might mean that your code could execute twice....

http://msdn.microsoft.com/en-us/library/aa363249(v=vs.85).aspx
Title: Re: Activated only with drive G:
Post by: Magnum on March 27, 2011, 01:19:34 AM
Will sleep on this one.


Title: Re: Activated only with drive G:
Post by: qWord on March 27, 2011, 01:49:22 AM
it is simple but it works:
(user CTRL+SHIFT+Q to quit the program)
Quoteinclude masm32rt.inc

DBT_DEVICEARRIVAL    EQU 8000h
DBT_DEVTYP_VOLUME   EQU 2

DEV_BROADCAST_HDR struct
    dbch_size      DWORD ?
    dbch_devicetype   DWORD ?
    dbch_reserved   DWORD ?
DEV_BROADCAST_HDR ends
PDEV_BROADCAST_HDR typedef ptr DEV_BROADCAST_HDR
DEV_BROADCAST_VOLUME struct
    dbcv_size      DWORD   ?
    dbcv_devicetype DWORD   ?
    dbcv_reserved   DWORD   ?
    dbcv_unitmask   DWORD   ?
    dbcv_flags      WORD   ?
DEV_BROADCAST_VOLUME ends
PDEV_BROADCAST_VOLUME typedef ptr DEV_BROADCAST_VOLUME

WndProc proto hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.data
    szCmd db 'C:\windows\system32\xcopy.exe "C:\masm32" "G:\backup" /E /Y',0
.data?
    hInstance   HINSTANCE   ?
    pcbWndProc   PVOID      ?
.code
main proc
LOCAL msg:MSG

    mov esi,rv(AddAtom,"idhk")
    invoke RegisterHotKey,0,esi,MOD_CONTROL or MOD_SHIFT,VK_Q
    mov edi,rv(CreateWindowEx,0,"button",0,0,-100,-100,10,10,0,0,hInstance,0)
    mov pcbWndProc,rv(SetWindowLong,edi,GWL_WNDPROC,OFFSET WndProc)

    .while 1
        invoke GetMessage,ADDR msg,0,0,0
        .break .if !eax || eax == -1 || (msg.message == WM_HOTKEY && msg.wParam == esi)
    .endw
   
    invoke ExitProcess,0
   
main endp

WndProc proc uses edi hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL sui:STARTUPINFO
LOCAL pi:PROCESS_INFORMATION

    .if uMsg == WM_DEVICECHANGE
        .if wParam == DBT_DEVICEARRIVAL
            mov edi,lParam
            .if [edi].DEV_BROADCAST_HDR.dbch_devicetype == DBT_DEVTYP_VOLUME
                .if ![edi].DEV_BROADCAST_VOLUME.dbcv_flags
                    mov eax,[edi].DEV_BROADCAST_VOLUME.dbcv_unitmask
                    bsf eax,eax
                    lea edx,[eax+'A']
                    .if edx == 'G'
                        invoke RtlZeroMemory,ADDR sui,sizeof sui
                        mov sui.cb,sizeof sui
                        fn CreateProcess,0,OFFSET szCmd,0,0,0,CREATE_NEW_CONSOLE,0,0,ADDR sui,ADDR pi
                        ;invoke WaitForSingleObject,pi.hProcess,INFINITE
                    .endif
                .endif
            .endif
        .endif
    .else
        invoke CallWindowProc,pcbWndProc,hWnd,uMsg,wParam,lParam
        ret
    .endif

    xor eax,eax
    ret   
   
WndProc endp
end main
Title: Re: Activated only with drive G:
Post by: Magnum on March 27, 2011, 07:37:04 AM
I need it to run a batch file.

This isn't working.


WndProc proto hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

.data
    szCmd db '"%s" /c "C:\Bat\BAK_ALL.bat"'

.data?
    hInstance   HINSTANCE   ?
    pcbWndProc   PVOID      ?

.code

main proc
LOCAL msg:MSG

    mov esi,rv(AddAtom,"idhk")
    invoke RegisterHotKey,0,esi,MOD_CONTROL or MOD_SHIFT,VK_Q
    mov edi,rv(CreateWindowEx,0,"button",0,0,-100,-100,10,10,0,0,hInstance,0)
    mov pcbWndProc,rv(SetWindowLong,edi,GWL_WNDPROC,OFFSET WndProc)

    .while 1
        invoke GetMessage,ADDR msg,0,0,0
        .break .if !eax || eax == -1 || (msg.message == WM_HOTKEY && msg.wParam == esi)
    .endw
   
    invoke ExitProcess,0
   
main endp

WndProc proc uses edi hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL sui:STARTUPINFO
LOCAL pi:PROCESS_INFORMATION

    .if uMsg == WM_DEVICECHANGE
        .if wParam == DBT_DEVICEARRIVAL
            mov edi,lParam
            .if [edi].DEV_BROADCAST_HDR.dbch_devicetype == DBT_DEVTYP_VOLUME
                .if ![edi].DEV_BROADCAST_VOLUME.dbcv_flags
                    mov eax,[edi].DEV_BROADCAST_VOLUME.dbcv_unitmask
                    bsf eax,eax
                    lea edx,[eax+'A']
                    .if edx == 'J' ; Drive letter
                        invoke RtlZeroMemory,ADDR sui,sizeof sui

Title: Re: Activated only with drive G:
Post by: ragdog on March 27, 2011, 11:23:35 AM
invoke GetEnvironmentVariable, CTEXT('ComSpec'), addr szComspec, sizeof szComspec
invoke wsprintf, addr @Result, CTEXT('"%s" /c "bat.cmd"'), addr szComspec
invoke WinExec,addr @Result,SW_SHOW
Title: Re: Activated only with drive G:
Post by: Magnum on March 27, 2011, 01:07:26 PM
It would not work.

I decided to use some earlier code and just turn on my printer each time.

Title: Re: Activated only with drive G:
Post by: qWord on March 27, 2011, 03:14:48 PM
Magnum,
you only need to change the commandline:

szCmd db 'C:\windows\system32\cmd.exe /C "C:\test.bat"',0
Title: Re: Activated only with drive G:
Post by: dedndave on March 27, 2011, 04:36:04 PM
this may be helpful, too - at least while debugging your code
/C      Carries out the command specified by string and then terminates
/K      Carries out the command specified by string but remains

by using /K, it is easier to tell if the shell is executed
Title: Re: Activated only with drive G:
Post by: Magnum on March 27, 2011, 04:44:23 PM
Thanks Qword.

It works perfectly now and I don't have to turn on my printer.

Title: Re: Activated only with drive G:
Post by: Magnum on March 27, 2011, 05:11:47 PM
Completed project attached.
Title: Re: Activated only with drive G:
Post by: Magnum on March 31, 2011, 06:50:46 PM
Not quite finished.

I need to add a check for drive g: to this code.

Do I add another .if after fnCreateProcess or after the .endif ?


    .if uMsg == WM_DEVICECHANGE
        .if wParam == DBT_DEVICEARRIVAL
            mov edi,lParam
            .if [edi].DEV_BROADCAST_HDR.dbch_devicetype == DBT_DEVTYP_VOLUME
                .if ![edi].DEV_BROADCAST_VOLUME.dbcv_flags
                    mov eax,[edi].DEV_BROADCAST_VOLUME.dbcv_unitmask
                    bsf eax,eax
                    lea edx,[eax+'A']
                    .if edx == 'J'
                        invoke RtlZeroMemory,ADDR sui,sizeof sui
                        mov sui.cb,sizeof sui
                        fn CreateProcess,0,OFFSET szCmd,0,0,0,CREATE_NEW_CONSOLE,0,0,ADDR sui,ADDR pi
                    .endif
                .endif
            .endif
        .endif
    .else

Title: Re: Activated only with drive G:
Post by: oex on March 31, 2011, 10:24:34 PM
                    .if edx == 'J' || edx == 'G'
                        invoke RtlZeroMemory,ADDR sui,sizeof sui
                        mov sui.cb,sizeof sui
                        fn CreateProcess,0,OFFSET szCmd,0,0,0,CREATE_NEW_CONSOLE,0,0,ADDR sui,ADDR pi
                    .endif


or

                    .if edx == 'J'
                        invoke RtlZeroMemory,ADDR sui,sizeof sui
                        mov sui.cb,sizeof sui
                        fn CreateProcess,0,OFFSET szCmd,0,0,0,CREATE_NEW_CONSOLE,0,0,ADDR sui,ADDR pi
                    .elseif edx == 'G'
; A different condition here....
                    .endif
Title: Re: Activated only with drive G:
Post by: Magnum on March 31, 2011, 11:06:57 PM
Thanks oex.

Is || the same as an OR statement ?

I did a search for || and OR but didn't find anything.



Title: Re: Activated only with drive G:
Post by: qWord on March 31, 2011, 11:19:27 PM
C\C++ tutorial (http://www.cprogramming.com/tutorial.html#c++tutorial)
Title: Re: Activated only with drive G:
Post by: oex on April 01, 2011, 12:35:05 AM
Quote from: Magnum on March 31, 2011, 11:06:57 PM
Is || the same as an OR statement ?

Yes but I am unaware if in ASM they operate at different precedence levels....
http://www.php.net/manual/en/language.operators.precedence.php

Also note that
.if edx == 'J' || edx == 'G'
This is 1 condition.... This will check both and execute if 1 matches....