From 1dec9750bed16eaeff97cf88374954d5ebde383c Mon Sep 17 00:00:00 2001 From: Sergey Khodych Date: Thu, 28 Aug 2008 01:00:19 +0300 Subject: mpr: Improve stubs for WNetGetUniversalName. --- dlls/mpr/wnet.c | 235 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 188 insertions(+), 47 deletions(-) diff --git a/dlls/mpr/wnet.c b/dlls/mpr/wnet.c index bf4ddb8..ca6c719 100644 --- a/dlls/mpr/wnet.c +++ b/dlls/mpr/wnet.c @@ -1852,40 +1852,154 @@ DWORD WINAPI WNetSetConnectionW( LPCWSTR lpName, DWORD dwProperty, DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpBufferSize ) { - DWORD err, size; + int len; + DWORD ret = 0; + LPWSTR wideLocalPath = NULL; + LPVOID wideBuffer = NULL; + DWORD localBufferSize = 0; + LPDWORD lpLocalBufferSize = NULL; FIXME( "(%s, 0x%08X, %p, %p): stub\n", - debugstr_a(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize); - - switch (dwInfoLevel) - { - case UNIVERSAL_NAME_INFO_LEVEL: + debugstr_a(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize ); + if ( lpLocalPath ) { - LPUNIVERSAL_NAME_INFOA info = (LPUNIVERSAL_NAME_INFOA)lpBuffer; - - size = sizeof(*info) + lstrlenA(lpLocalPath) + 1; - if (*lpBufferSize < size) + len = MultiByteToWideChar( CP_ACP, 0, lpLocalPath, -1, NULL, 0 ); + if ( !len ) { - err = WN_MORE_DATA; - break; + ret = GetLastError(); + goto done; + } + wideLocalPath = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + if ( !wideLocalPath ) + { + ret = WN_OUT_OF_MEMORY; + goto done; + } + if ( !MultiByteToWideChar(CP_ACP, 0, lpLocalPath, -1, wideLocalPath, len) ) + { + ret = GetLastError(); + goto done; + } + if ( lpBufferSize ) + { + lpLocalBufferSize = &localBufferSize; + if ( lpBuffer ) + { + switch ( dwInfoLevel ) + { + case UNIVERSAL_NAME_INFO_LEVEL: + localBufferSize = sizeof( UNIVERSAL_NAME_INFOA ); + break; + case REMOTE_NAME_INFO_LEVEL: + localBufferSize = sizeof( REMOTE_NAME_INFOA ); + break; + default: + ret = WN_BAD_VALUE; + goto done; + break; + } + if ( *lpBufferSize > localBufferSize ) + { + localBufferSize = sizeof(WCHAR)*(*lpBufferSize - localBufferSize) + localBufferSize; + wideBuffer = HeapAlloc( GetProcessHeap(), 0, localBufferSize ); + if ( !wideBuffer ) + { + ret = WN_OUT_OF_MEMORY; + goto done; + } + } + } } - info->lpUniversalName = (char *)info + sizeof(*info); - lstrcpyA(info->lpUniversalName, lpLocalPath); - *lpBufferSize = size; - err = WN_NO_ERROR; - break; } - case REMOTE_NAME_INFO_LEVEL: - err = WN_NO_NETWORK; - break; - - default: - err = WN_BAD_VALUE; - break; + ret = WNetGetUniversalNameW ( wideLocalPath, dwInfoLevel, + wideBuffer, lpLocalBufferSize ); + if ( NO_ERROR == ret ) + { + switch ( dwInfoLevel ) + { + case UNIVERSAL_NAME_INFO_LEVEL: + { + LPUNIVERSAL_NAME_INFOW lpUniNameInfoW = (LPUNIVERSAL_NAME_INFOW)wideBuffer; + LPUNIVERSAL_NAME_INFOA lpUniNameInfoA = (LPUNIVERSAL_NAME_INFOA)lpBuffer; + len = WideCharToMultiByte( CP_ACP, 0, lpUniNameInfoW->lpUniversalName, + -1, NULL, 0, NULL, NULL ); + if ( !len ) + { + ret = GetLastError(); + goto done; + } + if ( (UINT)len > (*lpBufferSize - sizeof( UNIVERSAL_NAME_INFOA ) ) ) + { + *lpBufferSize = len; + ret = ERROR_MORE_DATA; + goto done; + } + lpUniNameInfoA->lpUniversalName = (LPSTR)( (LPBYTE)lpBuffer + sizeof( UNIVERSAL_NAME_INFOA ) ); + if ( !WideCharToMultiByte( CP_ACP, 0, lpUniNameInfoW->lpUniversalName, + -1, lpUniNameInfoA->lpUniversalName, + len, NULL, NULL ) ) + { + ret = GetLastError(); + goto done; + } + } + break; + case REMOTE_NAME_INFO_LEVEL: + { + + DWORD index; + DWORD offset = sizeof ( REMOTE_NAME_INFOA ); + LPREMOTE_NAME_INFOW lpRemNameInfoW = (LPREMOTE_NAME_INFOW)wideBuffer; + LPREMOTE_NAME_INFOA lpRemNameInfoA = (LPREMOTE_NAME_INFOA)lpBuffer; + LPWSTR lpwStrIn[3] = { lpRemNameInfoW->lpUniversalName, + lpRemNameInfoW->lpConnectionName, + lpRemNameInfoW->lpRemainingPath }; + LPSTR *lplpStrOut[3] = { &lpRemNameInfoA->lpUniversalName, + &lpRemNameInfoA->lpConnectionName, + &lpRemNameInfoA->lpRemainingPath }; + + for ( index = 0; index *lpBufferSize ) + { + *lpBufferSize = len; + ret = ERROR_MORE_DATA; + goto done; + } + *lplpStrOut[index] = (LPSTR)( (LPBYTE)lpBuffer + offset ); + len = WideCharToMultiByte( CP_ACP, 0, lpwStrIn[index], -1, *lplpStrOut[index], len, NULL, NULL ); + if ( !len ) + { + ret = GetLastError(); + goto done; + } + offset+=len; + } + } + break; + } } - - SetLastError(err); - return err; + else if ( ERROR_MORE_DATA == ret ) + *lpBufferSize = *lpLocalBufferSize; + done: + if ( wideLocalPath ) + HeapFree( GetProcessHeap(), 0 , wideLocalPath ); + if ( wideBuffer ) + HeapFree( GetProcessHeap(), 0 , wideBuffer ); + SetLastError( ret ); + TRACE("Returning %d\n", ret); + return ret; } /***************************************************************** @@ -1895,37 +2009,64 @@ DWORD WINAPI WNetGetUniversalNameW ( LPCWSTR lpLocalPath, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpBufferSize ) { DWORD err, size; + WCHAR drive[3]={0}; FIXME( "(%s, 0x%08X, %p, %p): stub\n", - debugstr_w(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize); + debugstr_w(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize ); - switch (dwInfoLevel) + if ( !lpLocalPath ) { - case UNIVERSAL_NAME_INFO_LEVEL: + err = ERROR_INVALID_ADDRESS; + goto done; + } + if ( !lpBuffer && !lpBufferSize ) { - LPUNIVERSAL_NAME_INFOW info = (LPUNIVERSAL_NAME_INFOW)lpBuffer; - - size = sizeof(*info) + (lstrlenW(lpLocalPath) + 1) * sizeof(WCHAR); - if (*lpBufferSize < size) - { - err = WN_MORE_DATA; - break; - } - info->lpUniversalName = (LPWSTR)((char *)info + sizeof(*info)); - lstrcpyW(info->lpUniversalName, lpLocalPath); - *lpBufferSize = size; - err = WN_NO_ERROR; - break; + err = ERROR_INVALID_PARAMETER; + goto done; + } + size = lstrlenW( lpLocalPath ); + if ( size < 2 || ':' != lpLocalPath[1] ) + { + err = ERROR_BAD_DEVICE; + goto done; + } + if ( !lstrcpynW( drive, lpLocalPath, sizeof( drive )/sizeof( drive[0] ) ) ) + { + err = ERROR_INVALID_PARAMETER; + goto done; } - case REMOTE_NAME_INFO_LEVEL: + if ( DRIVE_REMOTE != GetDriveTypeW( drive ) ) + { + err = ERROR_NOT_CONNECTED; + goto done; + } + switch (dwInfoLevel) + { + case UNIVERSAL_NAME_INFO_LEVEL: + { + LPUNIVERSAL_NAME_INFOW info = (LPUNIVERSAL_NAME_INFOW)lpBuffer; + + size = sizeof(*info) + (size + 1) * sizeof(WCHAR); + if (*lpBufferSize < size) + { + *lpBufferSize = size; + err = WN_MORE_DATA; + break; + } + info->lpUniversalName = (LPWSTR)((char *)info + sizeof(*info)); + lstrcpyW(info->lpUniversalName, lpLocalPath); + *lpBufferSize = size; + err = WN_NO_ERROR; + break; + } + case REMOTE_NAME_INFO_LEVEL: err = WN_NO_NETWORK; break; - - default: + default: err = WN_BAD_VALUE; break; } - + done: SetLastError(err); return err; } -- 1.5.3.3