NtOpenSymbolicLinkObject выдает ошибку, что я не так делаю?

Тема в разделе "WASM.WIN32", создана пользователем marty77, 17 апр 2009.

  1. marty77

    marty77 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2009
    Сообщения:
    6
    Здравствуйте!

    Код такой:
    Код (Text):
    1. #ifndef SYMBOLIC_LINK_ALL_ACCESS
    2.     #define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
    3. #endif
    4.  
    5. ::std::wstring getSymbolicLinkDeviceName(const ::std::wstring &_deviceName)
    6.    {
    7.     HMODULE hNtDll = ::GetModuleHandleW( L"Ntdll.dll" );
    8.     if (!hNtDll) return ::std::wstring();
    9.  
    10.     NtOpenSymbolicLinkObjectFnPtr pNtOpenSymbolicLinkObject = (NtOpenSymbolicLinkObjectFnPtr)GetProcAddress( hNtDll, "NtOpenSymbolicLinkObject" );
    11.     if (!pNtOpenSymbolicLinkObject) return ::std::wstring();
    12.  
    13.     NtCloseFnPtr pNtClose = (NtCloseFnPtr)GetProcAddress( hNtDll, "NtClose" );
    14.     if (!pNtClose) return ::std::wstring();
    15.  
    16.     NtQuerySymbolicLinkObjectFnPtr pNtQuerySymbolicLinkObject = (NtQuerySymbolicLinkObjectFnPtr)GetProcAddress( hNtDll, "NtQuerySymbolicLinkObject" );
    17.     if (!pNtQuerySymbolicLinkObject) return ::std::wstring();
    18.  
    19.     //::std::wstring deviceName = ::std::wstring(L"\\??\\") + getSerialDeviceNameOnly(_deviceName);     // \??\COM1 - 0xc0000033 - Object Name invalid
    20.     //::std::wstring deviceName = ::std::wstring(L"\\\\?\\") + getSerialDeviceNameOnly(_deviceName);    // \\.\COM1 - 0xc0000033
    21.     //::std::wstring deviceName = getSerialDeviceNameOnly(_deviceName);                                 // COM1 - 0xc000003b - Object Path Component was not a directory object.
    22.     ::std::wstring deviceName = _deviceName;                                                          // \\.\COM1 COM1 - 0xc0000033
    23.  
    24.     WCHAR linkNameBuf[1024];
    25.     size_t linkNameBufSize = sizeof(linkNameBuf)/sizeof(linkNameBuf[0]);
    26.     size_t deviceNameSize = deviceName.size();
    27.     if (deviceNameSize>(linkNameBufSize-1)) deviceNameSize = linkNameBufSize-1;
    28.     deviceName.copy( linkNameBuf, deviceNameSize, 0);
    29.     linkNameBuf[deviceNameSize] = 0;
    30.  
    31.     UNICODE_STRING linkName = { (USHORT)deviceNameSize, (USHORT)linkNameBufSize, linkNameBuf };
    32.  
    33.     OBJECT_ATTRIBUTES ObjectAttributes;
    34.     InitializeObjectAttributes( &ObjectAttributes, &linkName, 0, 0, 0 );
    35.  
    36.     HANDLE hLinkHandle = INVALID_HANDLE_VALUE;
    37.     NTSTATUS Status = pNtOpenSymbolicLinkObject( &hLinkHandle
    38.                                                , SYMBOLIC_LINK_ALL_ACCESS
    39.                                                , &ObjectAttributes
    40.                                                );
    41.     if (!NT_SUCCESS( Status )) // выдаваемые ошибки см. выше
    42.        return ::std::wstring();
    43.  
    44.     WCHAR linkNameTargetBuf[1024];
    45.     UNICODE_STRING linkTarget = { (USHORT)(sizeof(linkNameTargetBuf)/sizeof(linkNameTargetBuf[0])), 0, linkNameTargetBuf };
    46.     Status = pNtQuerySymbolicLinkObject( hLinkHandle
    47.                                        , &linkTarget
    48.                                        , 0
    49.                                        );
    50.     pNtClose( hLinkHandle );
    51.     if (!NT_SUCCESS( Status ))
    52.        return ::std::wstring();
    53.  
    54.     return ::std::wstring( linkNameTargetBuf, linkTarget.Length );
    55.    }
    Как для COM порта получить имя устройства?
     
  2. RET

    RET Well-Known Member

    Публикаций:
    17
    Регистрация:
    5 янв 2008
    Сообщения:
    789
    Адрес:
    Jabber: darksys@sj.ms
    Для дисков:
    (HANDLE) hDevice, // handle to device
    IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, // dwIoControlCode
    NULL, // lpInBuffer
    0, // nInBufferSize
    (LPVOID) lpOutBuffer, // output buffer
    (DWORD) nOutBufferSize, // size of output buffer
    (LPDWORD) lpBytesReturned, // number of bytes returned
    (LPOVERLAPPED) lpOverlapped // OVERLAPPED structure
    );
    для COM портов \\Device\\Serial0 + ф-ция RtlDosPathNameToNtPathName_U
    \\\\.\\COM1 - это для WIN32 подсистемы.
     
  3. marty77

    marty77 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2009
    Сообщения:
    6
    А нельзя ли чуть поподробнее?
    Мне надо имя ком порта (COMX, \\.\COMX) преобразовать в имя устройства \\Device\\SerialX.
    Вычитал, что '\??\COMX' это симлинк на \\Device\\SerialX и это должно как раз разрешаться функциями NtOpenSymbolicLinkObject/NtQuerySymbolicLinkObject. Но у меня почему-то не заработало, ну и я решил по разному еще попробовать, но ни один способ не заработал.
    Насчет RtlDosPathNameToNtPathName не совсем понятно, она сразу преобразует COMX -> \\Device\\SerialX, или ее результат надо передать в Nt*SymbolicLinkObject?
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Код (Text):
    1.     OBJECT_ATTRIBUTES Oa;
    2.     UNICODE_STRING Ua;
    3.     NTSTATUS Status;
    4.     HANDLE LinkHandle;
    5.  
    6.     RtlInitUnicodeString (&Ua, L"\\??\\COM3");
    7.     InitializeObjectAttributes (&Oa, &Ua, 0, 0, 0);
    8.  
    9.     Status = ZwOpenSymbolicLinkObject (
    10.         &LinkHandle,
    11.         STANDARD_RIGHTS_REQUIRED | 1,
    12.         &Oa
    13.         );
    14.  
    15.     WCHAR buffer[1024] = L"";
    16.     UNICODE_STRING Target = {0, sizeof(buffer)/sizeof(*buffer), buffer};
    17.  
    18.     Status = ZwQuerySymbolicLinkObject (LinkHandle, &Target, NULL);
    19.  
    20.     printf("%S\n", buffer);
    21.  
    22.     ZwClose (LinkHandle);
    шикарно пашет. ищи багу у себя, должно все работать.
     
  5. marty77

    marty77 New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2009
    Сообщения:
    6
    Нашел косяк.
    Даная функция инициализирует UNICODE_STRING таким образом, что все размеры измеряются в байтах, а я ручками инициализировал, наивно полагая, что размеры задаются в символах.