.386
.model flat, stdcall
option casemap :none

include windows.inc
include kernel32.inc
include shell32.inc
include user32.inc
include gdi32.inc
include winmm.inc
include advapi32.inc
include masm32.inc

include cdk.mac

includelib kernel32.lib
includelib shell32.lib
includelib user32.lib
includelib gdi32.lib
includelib winmm.lib
includelib advapi32.lib
includelib masm32.lib

; #########################################################################
; Функции инициализации
WinMain proto
MainWindowProc proto :DWORD, :DWORD, :DWORD, :DWORD
CreateMainWindow proto 
InitCDDrives proto
AddTrayIcon proto :DWORD
ShowTrayMenu proto :DWORD
DeleteTrayIcons proto
OpenCDDrive proto
CloseCDDrive proto
ExploreCD proto
OpenCDFolder proto
LaunchSystemCDPlayer proto
InstallAutorun proto
CheckAutorun proto
InitTrayMenu proto
AboutCDKProc proto :DWORD, :DWORD, :DWORD, :DWORD
AboutCDK proto
ExecuteDoor proto
SetWaitIcon proto :BOOL
; #########################################################################
WM_TRAY EQU WM_USER + 100
; #########################################################################
PUBLIC fAbout
; #########################################################################
IDM_OPEN     EQU 1001
IDM_CLOSE    EQU 1002
IDM_EXPLORER EQU 1003
IDM_FOLDER   EQU 1004
IDM_SYSPLAY  EQU 1005
IDM_CDPLAY   EQU 1006
IDM_OPTIONS  EQU 1007
IDM_ABOUT    EQU 1008
IDM_EXIT     EQU 1009
IDM_AUTOCDK  EQU 1010
IDM_LETTER   EQU 1011
IDM_WASM     EQU 1012
IDM_UG       EQU 1013
IDM_BIG      EQU 1014
; #########################################################################

.data

  szMainClass      db "maincdkclass", 0
  szMainWindow     db "maincdkwindow", 0
  szFmtStr         db "%s", 0
  szFmtCnt         db "%s%s", 0
  szFmtCDDrv       db "CD Drive [%s]", 0 
  szcdaudio        db "cdaudio",0
  szOpenDoor       db "set cdaudio door open wait", 0
  szCloseDoor      db "set cdaudio door closed wait", 0  
  szCdkMenu        db "cdkmenu", 0
  szSubKey         db "System\CurrentControlSet\control\MediaResources\mci\cdaudio", 0 
  szKey	         db "Default Drive", 0
  szExplore        db "explore", 0
  szOpen           db "open", 0
  szCdplay         db "\cdplayer.exe", 0
  szAutoKey        db "Software\Microsoft\Windows\CurrentVersion\Run", 0
  szAutoKeyValue   db "cdk", 0
  szAboutCDKDialog db "AboutCDKDialog", 0
  szLetter         db "mailto:chest@mail.ru", 0
  szWasmSite       db "http://www.wasm.boom.ru", 0
  szBigSite        db "http://www.b-i-g.boom.ru", 0
  szUgSite         db "http://www.guia.nm.ru", 0
  
  drvquan          dd 0
  fDrives          dd 10 dup (0)

.data?

  hInstance dd ?
  hwnd      dd ?
  szBuf     db MAX_PATH dup(?)
  lpDrives  dd 10 dup (?)
  hKey      dd ?
  bData     dd ?
  cdn       dd ?
  sm        dd ?
  fAbout    db ?

.code

start:

  invoke GetModuleHandle, NULL
  mov hInstance, eax  
  invoke CreateMainWindow
  invoke InitCDDrives
  invoke WinMain
  invoke ExitProcess, 0

WinMain proc
  LOCAL msg:MSG

  .while TRUE
    invoke GetMessage, addr msg, NULL, 0, 0
    .break.if (!eax)
    invoke TranslateMessage, addr msg
    invoke DispatchMessage, addr msg
  .endw  
  
  ret
  
WinMain endp    
; #########################################################################
MainWindowProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD 
  
  .if uMsg == WM_CREATE
  
    invoke InitTrayMenu
  
  .elseif uMsg == WM_DESTROY
  
    invoke DeleteTrayIcons
    invoke PostQuitMessage, 0 
    
  .elseif uMsg == WM_TRAY
  
    ; Сохранение wParam в глобальную переменную
    mtm cdn, wParam
    .if lParam == WM_RBUTTONDOWN
      invoke ShowTrayMenu, wParam
    .elseif lParam == WM_LBUTTONUP
      invoke ExecuteDoor  
    .endif    

  .elseif uMsg == WM_COMMAND
    
    mov eax, wParam  
    .if lParam == 0
      .if ax == IDM_EXIT
        invoke SendMessage, hWnd, WM_DESTROY, 0, 0
      .elseif ax == IDM_OPEN
        invoke OpenCDDrive        
      .elseif ax == IDM_CLOSE
        invoke CloseCDDrive        
      .elseif ax == IDM_EXPLORER
        invoke ExploreCD
      .elseif ax == IDM_FOLDER
        invoke OpenCDFolder
      .elseif ax == IDM_SYSPLAY
        invoke LaunchSystemCDPlayer
      .elseif ax == IDM_AUTOCDK
        invoke InstallAutorun  
      .elseif ax == IDM_ABOUT
        invoke AboutCDK
      .elseif ax == IDM_LETTER
        invoke ShellExecute, hwnd, addr szOpen, addr szLetter, NULL, NULL, 0 
      .elseif ax == IDM_WASM
        invoke ShellExecute, hwnd, addr szOpen, addr szWasmSite, NULL, NULL, 0 
      .elseif ax == IDM_BIG        
        invoke ShellExecute, hwnd, addr szOpen, addr szBigSite, NULL, NULL, 0 
      .elseif ax == IDM_UG        
        invoke ShellExecute, hwnd, addr szOpen, addr szUgSite, NULL, NULL, 0 
      .endif    
    .endif

  .else

    invoke DefWindowProc, hWnd, uMsg, wParam, lParam
    ret

  .endif
  
  xor eax, eax  
  ret

MainWindowProc endp
; #########################################################################
CreateMainWindow proc
  LOCAL wc:WNDCLASS
  
  mtm wc.style, CS_HREDRAW + CS_VREDRAW
  mtm wc.lpfnWndProc, offset MainWindowProc
  mov wc.cbClsExtra, 0
  mov wc.cbWndExtra, 0
  mtm wc.hInstance, hInstance
  invoke LoadIcon, NULL, IDI_APPLICATION
  mov wc.hIcon, eax
  invoke LoadCursor, NULL, IDC_ARROW
  mov wc.hCursor, eax
  mov wc.hbrBackground, COLOR_WINDOW
  mov wc.lpszMenuName, NULL
  mov wc.lpszClassName, offset szMainClass
  invoke RegisterClass, addr wc

  invoke CreateWindowEx, NULL, addr szMainClass, addr szMainWindow, WS_POPUP, \
         0, 0, 0, 0, NULL, NULL, hInstance, NULL
  mov hwnd, eax        
         

  ret

CreateMainWindow endp
; #########################################################################
InitCDDrives proc uses ebx esi

  ; Получаем строку, содержащую все логические диски
  invoke GetLogicalDriveStrings, MAX_PATH, addr szBuf 
  ; Анализируем полученную строку
  mov ebx, offset szBuf
  .repeat
    invoke GetDriveType, ebx
    .if eax == DRIVE_CDROM
      new 5
      mov esi, eax
      mov eax, 4
      mul drvquan
      add eax, offset lpDrives
      mov [eax], esi
      invoke CharUpper, ebx
      invoke wsprintf, esi, addr szFmtStr, ebx
      invoke wsprintf, addr szBuf, addr szFmtStr, ebx
      mov eax, offset szBuf
      add eax, 2
      xor edx, edx
      mov [eax], edx
      invoke AddTrayIcon, addr szBuf
      inc drvquan   
    .endif    
    add ebx, 4 
  .until byte ptr [ebx+1] == 0
  
  ret

InitCDDrives endp
; #########################################################################
AddTrayIcon proc uses ebx lpszDrvPath
  LOCAL nd:NOTIFYICONDATA 
  
  ; Инициализация данных
  mov nd.cbSize, sizeof NOTIFYICONDATA
  mtm nd.hwnd, hwnd
  mov ebx, drvquan
  mtm nd.uID, ebx
  mov nd.uCallbackMessage, WM_TRAY
  invoke LoadIcon, hInstance, 2001
  push eax
  pop nd.hIcon
  invoke wsprintf, addr nd.szTip, addr szFmtCDDrv, lpszDrvPath
  mov nd.uFlags, NIF_ICON + NIF_MESSAGE + NIF_TIP
  ; Добавление иконки
  invoke Shell_NotifyIcon, NIM_ADD, addr nd 

  ret

AddTrayIcon endp
; #########################################################################
ShowTrayMenu proc dcd:DWORD

  LOCAL pt:POINT

  ; Установка текущего CD-ROM'а
  invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, addr szSubKey, 0, KEY_WRITE, addr hKey	
  invoke RegSetValueEx, hKey, addr szKey, 0, REG_BINARY, addr dcd, sizeof dcd
  invoke RegCloseKey, hKey
  ; Получение необходимых хэндлов
  invoke GetCursorPos, addr pt
  invoke SetForegroundWindow, hwnd
  ; Установление свойств меню
  invoke CheckAutorun
  .if !eax
    invoke CheckMenuItem, sm, IDM_AUTOCDK, MF_BYCOMMAND + MF_CHECKED
  .else
    invoke CheckMenuItem, sm, IDM_AUTOCDK, MF_BYCOMMAND + MF_UNCHECKED    
  .endif
  mov eax, 4
  mul cdn
  add eax, offset lpDrives  
  invoke GetVolumeInformation, [eax], NULL, NULL, NULL, NULL, NULL, NULL, NULL  
  .if !eax    
    invoke EnableMenuItem, sm, IDM_EXPLORER, MF_BYCOMMAND + MF_GRAYED
    invoke EnableMenuItem, sm, IDM_FOLDER, MF_BYCOMMAND + MF_GRAYED
  .else    
    invoke EnableMenuItem, sm, IDM_EXPLORER, MF_BYCOMMAND + MF_ENABLED
    invoke EnableMenuItem, sm, IDM_FOLDER, MF_BYCOMMAND + MF_ENABLED
  .endif 
  ; Отображение меню
  invoke TrackPopupMenu, sm, TPM_RIGHTALIGN, pt.x, pt.y, NULL, hwnd, NULL
  invoke PostMessage,hwnd,WM_NULL,0,0

  ret

ShowTrayMenu endp
; #########################################################################
DeleteTrayIcons proc uses ebx
  LOCAL nd:NOTIFYICONDATA 

  ; Начальная инициализация nd
  mov nd.cbSize, sizeof NOTIFYICONDATA
  mtm nd.hwnd, hwnd
  ; Цикл удаления иконок
  xor ebx, ebx
  .while ebx < drvquan
    mov nd.uID, ebx
    invoke Shell_NotifyIcon, NIM_DELETE, addr nd
    inc ebx
  .endw
  
  ret

DeleteTrayIcons endp
; #########################################################################
OpenCDDrive proc
  
  ; Увеличиваем флаг на один
  mov eax, 4
  mul cdn
  add eax, offset fDrives
  mov dword ptr [eax], 1
  ; Открываем устройство, открываем дверцу, закрываем устройство
  invoke SetWaitIcon, TRUE
  invoke mciSendString, addr szOpenDoor, 0, 0, hwnd
  invoke SetWaitIcon, FALSE
  
  ret
  
OpenCDDrive endp  
; #########################################################################
CloseCDDrive proc
  
  ; Уменьшаем флаг на один
  mov eax, 4
  mul cdn
  add eax, offset fDrives
  mov dword ptr [eax], 0
  ; Открываем устройство, открываем дверцу, закрываем устройство
  invoke SetWaitIcon, TRUE
  invoke mciSendString, addr szCloseDoor, 0, 0, hwnd
  invoke SetWaitIcon, FALSE
  
  ret
  
CloseCDDrive endp  
; #########################################################################
ExploreCD proc

  mov eax, 4
  mul cdn
  add eax, offset lpDrives
  invoke ShellExecute, NULL, addr szExplore, [eax], NULL, NULL, SW_SHOW
  
  ret

ExploreCD endp
; #########################################################################
OpenCDFolder proc

  mov eax, 4
  mul cdn
  add eax, offset lpDrives
  invoke ShellExecute, NULL, addr szOpen, [eax], NULL, NULL, SW_SHOW
  
  ret

OpenCDFolder endp
; #########################################################################
LaunchSystemCDPlayer proc

  invoke GetWindowsDirectory, addr szBuf, MAX_PATH
  invoke wsprintf, addr szBuf, addr szFmtCnt, addr szBuf, addr szCdplay
  invoke ShellExecute, NULL, addr szOpen, addr szBuf, NULL, NULL, SW_SHOW
  
  ret

LaunchSystemCDPlayer endp
; #########################################################################
InstallAutorun proc
  LOCAL mi:MENUITEMINFO

  invoke GetMenuState, sm, IDM_AUTOCDK, MF_BYCOMMAND
  .if eax == MF_UNCHECKED
    invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, addr szAutoKey, 0, KEY_WRITE, addr hKey
    invoke GetModuleFileName, hInstance, addr szBuf, MAX_PATH
    invoke lstrlen, addr szBuf
    invoke RegSetValueEx, hKey, addr szAutoKeyValue, 0, REG_SZ, addr szBuf, eax
    invoke RegCloseKey, hKey   
  .elseif eax == MF_CHECKED
    invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, addr szAutoKey, 0, KEY_WRITE, addr hKey	
    invoke RegDeleteValue, hKey, addr szAutoKeyValue
    invoke RegCloseKey, hKey 
  .endif
  
  ret

InstallAutorun endp
; #########################################################################
CheckAutorun proc
  LOCAL rv:DWORD
  LOCAL bsize:DWORD

  mov bsize, MAX_PATH
  invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, addr szAutoKey, 0, KEY_READ, addr hKey
  invoke RegQueryValueEx, hKey, addr szAutoKeyValue, 0, addr rv, addr szBuf, addr bsize
  push eax
  invoke RegCloseKey, hKey
  pop eax
  
  ret

CheckAutorun endp
; #########################################################################
InitTrayMenu proc

  ; Получаем хэндл меню
  invoke LoadMenu, hInstance, addr szCdkMenu
  invoke GetSubMenu, eax, 0
  mov sm, eax
  ; Добавляем иконки
  invoke LoadBitmap, hInstance, 2002
  invoke SetMenuItemBitmaps, sm, IDM_OPEN, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2003
  invoke SetMenuItemBitmaps, sm, IDM_CLOSE, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2004
  invoke SetMenuItemBitmaps, sm, IDM_EXPLORER, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2005
  invoke SetMenuItemBitmaps, sm, IDM_FOLDER, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2006
  invoke SetMenuItemBitmaps, sm, IDM_SYSPLAY, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2007
  invoke SetMenuItemBitmaps, sm, IDM_ABOUT, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2008
  invoke SetMenuItemBitmaps, sm, IDM_EXIT, MF_BYCOMMAND, eax, eax 
  invoke LoadBitmap, hInstance, 2009
  invoke SetMenuItemBitmaps, sm, IDM_LETTER, MF_BYCOMMAND, eax, eax 

  ret

InitTrayMenu endp
; #########################################################################
AboutCDK proc

  .if fAbout
    ret
  .endif
  inc fAbout
  invoke DialogBoxParam, hInstance, addr szAboutCDKDialog, hwnd, addr AboutCDKProc, NULL
  
  ret

AboutCDK endp
; #########################################################################
ExecuteDoor proc

  ; Установка текущего CD-ROM'а
  invoke RegOpenKeyEx, HKEY_LOCAL_MACHINE, addr szSubKey, 0, KEY_WRITE, addr hKey	
  invoke RegSetValueEx, hKey, addr szKey, 0, REG_BINARY, addr cdn, sizeof cdn
  invoke RegCloseKey, hKey
  ; Закрытие или открытие CD-ROM'а
  mov eax, 4
  mul cdn
  add eax, offset fDrives
  xor edx, edx
  .if [eax] == edx
    inc dword ptr [eax]
    invoke OpenCDDrive
  .else
    dec dword ptr [eax]
    invoke CloseCDDrive
  .endif
  
  
  ret

ExecuteDoor endp
; #########################################################################
SetWaitIcon proc fIcon:BOOL
  LOCAL nd:NOTIFYICONDATA 
 
  ; Инициализация данных
  mov nd.cbSize, sizeof NOTIFYICONDATA
  mtm nd.hwnd, hwnd
  mov ebx, drvquan
  mtm nd.uID, cdn
  mov nd.uFlags, NIF_ICON
  .if fIcon
    invoke LoadIcon, hInstance, 2000
    mov nd.hIcon, eax
  .else
    invoke LoadIcon, hInstance, 2001
    mov nd.hIcon, eax  
  .endif
  ; Установка иконки
  invoke Shell_NotifyIcon, NIM_MODIFY, addr nd

  ret

SetWaitIcon endp
; #########################################################################

end start

