Атомы vs WinXP

Тема в разделе "WASM.BEGINNERS", создана пользователем Derebuser, 19 июл 2007.

  1. Derebuser

    Derebuser New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2007
    Сообщения:
    11
    Недавно написал прогу, которая в числе прочего не даёт запускаться двум экземплярам себя. Я это реализовал через атомы примерно так:
    Код (Text):
    1. .code
    2. start:
    3.     invoke GetModuleHandleA,NULL
    4.     mov hInst,eax
    5.  
    6.     invoke GlobalFindAtomA,addr AtomString
    7.     cmp eax,0
    8.     jne exitapp
    9.     invoke GlobalAddAtomA,addr AtomString
    10.     mov Atom,eax
    11.  
    12.     ;register class:
    13.     mov wcl.cbSize,sizeof wndclassex
    14.     mov wcl.style,CS_HREDRAW+CS_VREDRAW
    15.     mov wcl.lpfnWndProc,offset wndproc
    16.     mov wcl.cbClsExtra,0
    17.     mov wcl.cbWndExtra,0
    18.     mov eax,hInst
    19.     mov wcl.hInstance,eax
    20.     invoke LoadIconA,eax,1
    21.     mov wcl.hIcon,eax
    22.     invoke LoadCursorA,NULL,IDC_WAIT
    23.     mov wcl.hCursor,eax
    24.     mov wcl.hbrBackground,6
    25.     mov wcl.lpszMenuName,NULL
    26.     mov wcl.lpszClassName,offset clsname
    27.     mov wcl.hIconSm,NULL
    28.     invoke RegisterClassExA,addr wcl
    29.  
    30.     cmp eax,NULL
    31.     jne crwnd
    32.  
    33.     invoke MessageBoxA,NULL,addr msgerrtext,addr wndname,MB_OK+MB_ICONSTOP
    34.     jmp overone
    35. exitapp:    invoke MessageBoxA,NULL,addr alreadyexist,addr wndname,MB_OK+MB_ICONINFORMATION
    36. overone:    invoke ExitProcess,1
    37.  
    38. crwnd:
    39.     invoke CreateWindowExA,NULL,addr clsname,addr wndname,WS_OVERLAPPEDWINDOW,100,100,100,100,NULL,NULL,hInst,NULL
    40.     mov hWnd,eax
    41.     invoke ShowWindow,hWnd,SW_HIDE
    42.     invoke PostMessage,hWnd,WM_SHOWWINDOW,NULL,NULL
    43.     invoke UpdateWindow,hWnd
    44.  
    45.     mov flag,0
    46.  
    47.     invoke SetTimer,hWnd,1,30000,NULL
    48.     cmp eax,0
    49.     jne _loop
    50.  
    51.     invoke MessageBoxA,NULL,addr msgerrtext2,addr wndname,MB_OK+MB_ICONSTOP
    52.     invoke ExitProcess,2
    53.  
    54. _loop:
    55.     invoke GetMessageA,addr msg,NULL,0,0
    56.     cmp eax,0
    57.     je exitnormal
    58.     invoke TranslateMessage,addr msg
    59.     invoke DispatchMessageA,addr msg
    60.     jmp _loop
    61.  
    62. exitnormal:
    63.     bt flag,0
    64.     jnc delex
    65.     mov word ptr [temp],0a0dh
    66.     invoke CreateFile, addr logname, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    67.     cmp eax,-1
    68.     je _ferror2
    69.     mov hFile,eax
    70.     invoke setFilePointer,hFile,0,NULL,FILE_END
    71.     invoke WriteFile, hFile, addr temp, 2, addr rw, NULL
    72.     invoke CloseHandle,hFile
    73. delex:
    74.     invoke Shell_NotifyIconA,NIM_DELETE,addr tricon
    75. delatom:    invoke GlobalDeleteAtom,Atom
    76.     test eax,eax
    77.     jz delatom
    78.     jmp exit
    79. _ferror2:
    80.     invoke MessageBox,NULL,addr ferr,addr wndname,MB_OK+MB_ICONEXCLAMATION
    81.     jmp delex
    82. exit:   invoke ExitProcess,0
    Здесь привожу только ключевой участок кода.
    Проблема заключается в том, что у меня под Win98 всё работает как положено, а у друга под WinXP выводит тот самый "MessageBoxA,NULL,addr alreadyexist,addr wndname,MB_OK+MB_ICONINFORMATION".

    Может кто-нибудь знает почему так?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ATOM = WORD
    Проверять надо равенство нулю AX, а не EAX
     
  4. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Great
    думается, непринципиально ибо добрая половина софта проверяет bool как eax а не al... и т.п. А другая половина устанавливает флаги через "+" а не через "OR". /хотя всё это не есть гуд/
     
  5. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Derebuser
    а оно так сразу стало выводится или первый запуск прошел нормально? Сам столкнулся с этой проблемой. Подозреваю, что после закрытия программы атом просто не уничтожается, поэтому перешел на мутексы
     
  6. Derebuser

    Derebuser New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2007
    Сообщения:
    11
    Нет, сообщение выводится при первом запуске. А что касается "неудалившегося" атома, то это маловероятно:
    Код (Text):
    1. delatom:    invoke GlobalDeleteAtom,Atom
    2.     test eax,eax
    3.     jz delatom      ;если получилось,удалять ещё
    4.     jmp exit        ;если не получилось, значит все такие атомы удалены
    Как видите, пресловутый атом удаляется довольно жёстко.

    А что такое мутексы и где про них можно почитать?
     
  7. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    Код (Text):
    1.  
    2. _mutex db 'some identifier',0
    3. start:
    4.         invoke  OpenMutex,1F0001h,0,_mutex
    5.         test    eax,eax
    6.         jne     already_runin
    7.  
    8.         invoke  CreateMutex,0,0,_mutex
    9.         jmp     next00
    10.  
    11.   already_runin:
     
  8. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    А атомы - глобальная штука. Они же создаются при регистрации класса окна. И хранятся в системе до явного удаления и MSoft про это заметил верно. так что чистый код рулит и ExitProcess cleanup'у тута не поможет.
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Это принципиально и дело именно в этом, я проверил. Видно, они слегка криво реализованы и там не очищается старшая половина EAX перед выходом из GlobalFindAtomA.
     
  10. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Так и не обязана. Это ж не x64, чтоб процессором очищалось.
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    IceStudent
    тем более что не обязана) так что все равно надо проверять AX
     
  12. Derebuser

    Derebuser New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2007
    Сообщения:
    11
    FreeManCPM
    Спасибо

    Great
    Так что, в 98-ой очищается, а в ХР нет?
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Видно реализация такова, что в 98й случайно очищается, а в ХР нет. Говорят вот, что не обязано очищаться. Короче проверяй ax только.. старшую часть не трожь)
     
  14. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
    Можно ещё CreateMutex и уникальное имя использовать для этих целей. если после вызова GetLastError() скажет ERROR_ALREADY_EXISTS, то значит грузится 2й экземпляр.
     
  15. Derebuser

    Derebuser New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2007
    Сообщения:
    11
    Спасибо всем за помощь и советы. Думаю, тему можно считать закрытой.
     
  16. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    roman_pro
    GetLastError даже избыточно, Фриман дал правильный код.
     
  17. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Mental_Mirror
    с GetLastError слегка короче будет )
     
  18. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Mental_Mirror
    Фриман дал правильный код
    Заблуждаешься.

    Что будет если первая копия процесса успеет выполнить только OpenMutex, винда передаст управление второй копии, которая успеет выполнить OpenMutex и CreateMutex?
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    q_q
    Если сделать один вызов CreateMutex, то эта проблема исключается.. так что еще один аргумент )
     
  20. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    Great,q_q
    Ухты, спасибо! :) Теперь буду знать.