ShBrowseForFolder недосказанное

Тема в разделе "WASM.WIN32", создана пользователем kiosun, 21 ноя 2010.

  1. kiosun

    kiosun New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    6
    РЕДАКТИРОВАНО 23.11.2010 23:20 (постарался более подробно все описать)

    Вот код программы на C++ который получает IDList указатель из текстового названия каталога. Этот IDList указатель можно потом использовать в структуре BROWSEINFO конкретно параметр pidlRoot для задания корневого каталога для отображения функцией ShBrowseForFolder. Во всех примерах в интернете всегда параметр pidlRoot установлен в ноль, в том числе и по той ссылке что ниже оставил Flint_ta. В прикрепленном файле я постарался реализовать код получения IDList указателя из названия каталога, но что-то не так работает. С вызовом функции ShBrowseForFolder проблем нет, но из-за того, что не получается создать IDList указатель из названия каталога, соответственно не получается задать корневой каталог для отображения.

    Код (Text):
    1. BOOL GetItemIdListFromPath (LPWSTR lpszPath, LPITEMIDLIST *lpItemIdList)
    2. {
    3.    LPSHELLFOLDER pShellFolder = NULL;
    4.    HRESULT         hr;
    5.    ULONG         chUsed;
    6.  
    7.    // Get desktop IShellFolder interface
    8.    if (SHGetDesktopFolder (&pShellFolder) != NOERROR)
    9.       return FALSE;     // failed
    10.  
    11.    // convert the path to an ITEMIDLIST
    12.    hr = pShellFolder->ParseDisplayName (
    13.                   NULL,           // owner window
    14.                   NULL,           // reserved (must be NULL)
    15.                   lpszPath,       // folder name
    16.                   &chUsed,    // number of chars parsed
    17.                   lpItemIdList,   // ITEMIDLIST
    18.                   NULL            // attributes (can be NULL)
    19.                );
    20.  
    21.    if (FAILED(hr))
    22.    {
    23.       pShellFolder->Release();
    24.       *lpItemIdList = NULL;
    25.       return FALSE;
    26.    }
    27.  
    28.    pShellFolder->Release();
    29.    return TRUE;
    30. } // GetItemIdListFromPath
    Задача: сделать аналогичный вариант на MASM32, чтобы функция ShBrowseForFolder отображала для выбора только диск С:\ и его подкаталоги
    Вопросы:
    1) что неправильно в моем варианте вызова функции ParseDisplayName (в прикреплённом файле) ?
    2) Какова общая методика определения смещений методов объектов (тоесть как их искать) для их вызова в коде ассемблера (или может быть есть кардинально другой способ вызова методов объектов, чтобы не искать смещения) ?
     
  2. kiosun

    kiosun New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    6
    Есть такой вариант, если кто-то может, откомпилировать Сишный код и выложить здесь. Постараюсь сам разобраться.
     
  3. kiosun

    kiosun New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    6
  4. Flint_ta

    Flint_ta New Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    312
  5. kiosun

    kiosun New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    6
    отредактировал шапку, подробно описал что именно не получается, пример по ссылке выше не объясняет того, что нужно получить.
     
  6. _Lamer

    _Lamer Petr

    Публикаций:
    0
    Регистрация:
    19 ноя 2010
    Сообщения:
    9
    Адрес:
    Vitebsk
    kiosun
    А сам скомпилсть не можешь?
    вызов:
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3.     LPITEMIDLIST lpItemIdList = NULL;
    4.     GetItemIdListFromPath(L"C:\\", &lpItemIdList);
    5.     return 0;
    6. }
    реализация от MS VC 2008 Debug:
    Код (Text):
    1. BOOL GetItemIdListFromPath (LPWSTR lpszPath, LPITEMIDLIST *lpItemIdList)
    2. {
    3. 004113E0  push        ebp  
    4. 004113E1  mov         ebp,esp
    5. 004113E3  sub         esp,0E4h
    6. 004113E9  push        ebx  
    7. 004113EA  push        esi  
    8. 004113EB  push        edi  
    9. 004113EC  lea         edi,[ebp-0E4h]
    10. 004113F2  mov         ecx,39h
    11. 004113F7  mov         eax,0CCCCCCCCh
    12. 004113FC  rep stos    dword ptr es:[edi]
    13.    LPSHELLFOLDER pShellFolder = NULL;
    14. 004113FE  mov         dword ptr [pShellFolder],0
    15.    HRESULT         hr;
    16.    ULONG         chUsed;
    17.  
    18.    // Get desktop IShellFolder interface
    19.    if (SHGetDesktopFolder (&pShellFolder) != NOERROR)
    20. 00411405  mov         esi,esp
    21. 00411407  lea         eax,[pShellFolder]
    22. 0041140A  push        eax  
    23. 0041140B  call        dword ptr [__imp__SHGetDesktopFolder@4 (418338h)]
    24. 00411411  cmp         esi,esp
    25. 00411413  call        @ILT+330(__RTC_CheckEsp) (41114Fh)
    26. 00411418  test        eax,eax
    27. 0041141A  je          GetItemIdListFromPath+40h (411420h)
    28.       return FALSE;     // failed
    29. 0041141C  xor         eax,eax
    30. 0041141E  jmp         GetItemIdListFromPath+0B2h (411492h)
    31.  
    32.    // convert the path to an ITEMIDLIST
    33.    hr = pShellFolder->ParseDisplayName (
    34.                   NULL,           // owner window
    35.                   NULL,           // reserved (must be NULL)
    36.                   lpszPath,       // folder name
    37.                   &chUsed,    // number of chars parsed
    38.                   lpItemIdList,   // ITEMIDLIST
    39.                   NULL            // attributes (can be NULL)
    40.                );
    41. 00411420  mov         esi,esp
    42. 00411422  push        0    
    43. 00411424  mov         eax,dword ptr [lpItemIdList]
    44. 00411427  push        eax  
    45. 00411428  lea         ecx,[chUsed]
    46. 0041142B  push        ecx  
    47. 0041142C  mov         edx,dword ptr [lpszPath]
    48. 0041142F  push        edx  
    49. 00411430  push        0    
    50. 00411432  push        0    
    51. 00411434  mov         eax,dword ptr [pShellFolder]
    52. 00411437  mov         ecx,dword ptr [eax]
    53. 00411439  mov         edx,dword ptr [pShellFolder]
    54. 0041143C  push        edx  
    55. 0041143D  mov         eax,dword ptr [ecx+0Ch]
    56. 00411440  call        eax  
    57. 00411442  cmp         esi,esp
    58. 00411444  call        @ILT+330(__RTC_CheckEsp) (41114Fh)
    59. 00411449  mov         dword ptr [hr],eax
    60.  
    61.    if (FAILED(hr))
    62. 0041144C  cmp         dword ptr [hr],0
    63. 00411450  jge         GetItemIdListFromPath+96h (411476h)
    64.    {
    65.       pShellFolder->Release();
    66. 00411452  mov         eax,dword ptr [pShellFolder]
    67. 00411455  mov         ecx,dword ptr [eax]
    68. 00411457  mov         esi,esp
    69. 00411459  mov         edx,dword ptr [pShellFolder]
    70. 0041145C  push        edx  
    71. 0041145D  mov         eax,dword ptr [ecx+8]
    72. 00411460  call        eax  
    73. 00411462  cmp         esi,esp
    74. 00411464  call        @ILT+330(__RTC_CheckEsp) (41114Fh)
    75.       *lpItemIdList = NULL;
    76. 00411469  mov         eax,dword ptr [lpItemIdList]
    77. 0041146C  mov         dword ptr [eax],0
    78.       return FALSE;
    79. 00411472  xor         eax,eax
    80. 00411474  jmp         GetItemIdListFromPath+0B2h (411492h)
    81.    }
    82.  
    83.    pShellFolder->Release();
    84. 00411476  mov         eax,dword ptr [pShellFolder]
    85. 00411479  mov         ecx,dword ptr [eax]
    86. 0041147B  mov         esi,esp
    87. 0041147D  mov         edx,dword ptr [pShellFolder]
    88. 00411480  push        edx  
    89. 00411481  mov         eax,dword ptr [ecx+8]
    90. 00411484  call        eax  
    91. 00411486  cmp         esi,esp
    92. 00411488  call        @ILT+330(__RTC_CheckEsp) (41114Fh)
    93.    return TRUE;
    94. 0041148D  mov         eax,1
    95. } // GetItemIdListFromPath
    96. 00411492  push        edx  
    97. 00411493  mov         ecx,ebp
    98. 00411495  push        eax  
    99. 00411496  lea         edx,[ (4114B8h)]
    100. 0041149C  call        @ILT+135(@_RTC_CheckStackVars@8) (41108Ch)
    101. 004114A1  pop         eax  
    102. 004114A2  pop         edx  
    103. 004114A3  pop         edi  
    104. 004114A4  pop         esi  
    105. 004114A5  pop         ebx  
    106. 004114A6  add         esp,0E4h
    107. 004114AC  cmp         ebp,esp
    108. 004114AE  call        @ILT+330(__RTC_CheckEsp) (41114Fh)
    109. 004114B3  mov         esp,ebp
    110. 004114B5  pop         ebp  
    111. 004114B6  ret
    реализация от MS VC 2008 Release:
    Код (Text):
    1. int _tmain(int argc, _TCHAR* argv[])
    2. {
    3. 00401000  sub         esp,0Ch
    4.     LPITEMIDLIST lpItemIdList = NULL;
    5.     GetItemIdListFromPath(L"C:\\", &lpItemIdList);
    6. 00401003  lea         eax,[esp]
    7. 00401006  push        eax  
    8. 00401007  mov         dword ptr [esp+8],0
    9. 0040100F  mov         dword ptr [esp+4],0
    10. 00401017  call        dword ptr [__imp__SHGetDesktopFolder@4 (4020A4h)]
    11. 0040101D  test        eax,eax
    12. 0040101F  jne         wmain+4Eh (40104Eh)
    13. 00401021  mov         eax,dword ptr [esp]
    14. 00401024  mov         ecx,dword ptr [eax]
    15. 00401026  push        0    
    16. 00401028  lea         edx,[esp+8]
    17. 0040102C  push        edx  
    18. 0040102D  lea         edx,[esp+10h]
    19. 00401031  push        edx  
    20. 00401032  push        offset string L"C:\\" (4020F4h)
    21. 00401037  push        0    
    22. 00401039  push        0    
    23. 0040103B  push        eax  
    24. 0040103C  mov         eax,dword ptr [ecx+0Ch]
    25. 0040103F  call        eax  
    26. 00401041  test        eax,eax
    27. 00401043  mov         eax,dword ptr [esp]
    28. 00401046  mov         ecx,dword ptr [eax]
    29. 00401048  mov         edx,dword ptr [ecx+8]
    30. 0040104B  push        eax  
    31. 0040104C  call        edx  
    32.     return 0;
    33. 0040104E  xor         eax,eax
    34. }
    35. 00401050  add         esp,0Ch
    36. 00401053  ret
     
  7. kiosun

    kiosun New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    6
    Поправил код. Теперь функцию IShellFolder->ParseDisplayName вызываю так(этот вызов идентичен тому, что в листингах выше):
    Str1 db "d:\Pictures",0
    ..............
    push NULL
    lea eax, BI.pidlRoot
    push eax
    push NULL
    push offset Str1
    push NULL
    push hWnd
    mov eax, pShellFolder
    push eax
    mov eax, [eax]
    call dword ptr [eax+12]

    Если Str1 равно "d:\Pictures" или "d:\Pictures\" или "d:\1.txt" (этот каталог и файл точно существуют) , то функция возвращает значение 80070002 (тип HRESULT) - как я понял это означает The system cannot find the file specified.

    что не так?
     
  8. BaGiE

    BaGiE New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2005
    Сообщения:
    84
    Адрес:
    Mordor
    COM\OLE обычно использует юникод
    см. внимательней ParseDisplayName(...[in] LPWSTR pszDisplayName..)
    может в этом и причина. и я не знаю как в масме но для фасма есть в стандартной поставке макросы для работы с COM. неужели для масм ничего нет? сомнительно как-то.
     
  9. kiosun

    kiosun New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    6
    Спасибо, BaGiE, всего-то надо было использовать Юникод строку, всё из-за моей невнимательности.

    То что в FASM есть макросы для работы с COM я обязательно почитаю, но что есть такие же в MASM или есть какая-то дополнительная библиотека для этих целей, я ничего не знаю. Буду копать, может кто и подскажет чего.

    П.С. первое что сразу нашлось: в более ранних версиях MASM вроде как была папка COM, у меня же стоит последняя версия - такой папки нет ...