Нашёл исходник программы, для работы с сидиромом, писанная на ассемблере (MASM), мне там нужно несколько строчек перевести в дельфийский ассеблер: Код (Text): ; Закрытие или открытие 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 смысл кода в том, что он определяет состояние лотка (открыт/закрыт), в Дельфе это криво определяется (если диска нет - то лоток открыт), я запутался, помогите начинающему. Вот исходник: Код (Text): .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 С уважением.
Moral_Freak Тебе не ассемблерный код нужен. Используй только API. Код (Text): mciSendString("set cdaudio door open wait", 0, 0, [идентификатор окна приложения]) - для открытия лотка mciSendString(set cdaudio door closed wait, 0, 0, [идентификатор окна приложения]) - для закрытия лотка И где-нибудь сохраняй флаг текущего состояния лотка (открыт/закрыт).
Нет, нет открывать лотки и закрывать лотки я умею. Я не могу в Делфи корректно определить состояние лотка, т.е. драйвер делает это криво, если сидюк закрыт и диска там нету - то он считает что лоток открыт! Моя программа не висит в процессах, она запускается, выполняет действие и закрывается, можно конечно сохранять в глобальных атомах, НО после перезагрузки они ведь подчищаются. Автор программы решил эту проблему 4 строчками, помогите это перегнать в Делфи.
Moral_Freak Если и решил, то не 4-мя строчками. Во всем коде разьбираться лень, но приведенный тобой кусок кода на пскале выглядит просто: Код (Text): var fDrives:array[0..9] of integer; //флаги состояния дисководов, 1 - открыт, 0 - закрыт cdn:integer; //номер дисковода procedure ExecuteDor; begin //.. запись cdn в реестр if fDrives[cdn] = 0 then OpenCDDrive //устанавливает fDrives[cdn]:=1; else CloseCDDrive; //устанавливает fDrives[cdn]:=0; end; Т.е. просто при каждом открытии\закрытии устанавливает\сбрасывает флаг fDrives[cdn]. Причем элементарный поиск строки показывает, что fDrives нигде больше в коде не используется, т.е. никак специально не инициализируется и значит по умолчанию предполагается, что при запуске проги дисковод закрыт PS: И индексация массива кстати реализована дебильно через mul, вместо стандартной Код (Text): mov eax,cdn lea eax,[eax*4+offset fDrives]
Значит всё-таки вот так: Код (Text): И где-нибудь сохраняй флаг текущего состояния лотка (открыт/закрыт). А вообще на низкоуровневом программировани, как определить состояние лотка сидирома?
Moral_Freak Код (Text): А вообще на низкоуровневом программировани, как определить состояние лотка сидирома? У меня не получилось. Может драйвер оборудования может это делать. Но врядли это будет универсальное решение.
Moral_Freak Хотя, знаешь ли, кажется есть возможность http://expert.delphi.int.ru/question/1550/ Опять же API. Код (Text): mciSendString("status cdaudio mode", lpstrBuffer, uLength, [идентификатор окна приложения]) где: lpstrBuffer - строковый буфер. Если лоток привода открыт, в буфере будет находиться строка "open". Если лоток привода закрыт, но диска в нем нет, в буфере будет находиться строка "open". Если лоток привода закрыт и вставлен диск, в буфере будет находиться строка "stopped". uLength - длина строкового буфера А вообще свойство "mode" может возвращать значения "not ready", "paused", "playing" и "stopped". Некоторые девайсы дополнительно могут возвращать значения "open", "parked", "recording" и "seeking".