Reactos
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 925 lines 27 kB view raw
1/* NFSv4.1 client for Windows 2 * Copyright © 2012 The Regents of the University of Michigan 3 * 4 * Olga Kornievskaia <aglo@umich.edu> 5 * Casey Bodley <cbodley@umich.edu> 6 * 7 * This library is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation; either version 2.1 of the License, or (at 10 * your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, but 13 * without any warranty; without even the implied warranty of merchantability 14 * or fitness for a particular purpose. See the GNU Lesser General Public 15 * License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 */ 21 22#include <windows.h> 23#include <npapi.h> 24#include <devioctl.h> 25#include <strsafe.h> 26 27#include "nfs41_driver.h" 28#include "nfs41_np.h" 29#include "options.h" 30 31#include <pseh/pseh2.h> 32 33#ifdef DBG 34#define DbgP(_x_) NFS41DbgPrint _x_ 35#else 36#define DbgP(_x_) 37#endif 38#define TRACE_TAG L"[NFS41_NP]" 39#define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor ) 40 41 42ULONG _cdecl NFS41DbgPrint( __in LPTSTR Format, ... ) 43{ 44 ULONG rc = 0; 45 TCHAR szbuffer[256]; 46 47 va_list marker; 48 va_start( marker, Format ); 49 { 50#ifndef __REACTOS__ 51 //StringCchVPrintfW( szbuffer, 127, Format, marker ); 52 StringCchVPrintfW( szbuffer, 256, Format, marker ); 53 szbuffer[255] = (TCHAR)0; 54#else 55 StringCchVPrintf( szbuffer, 256, Format, marker ); 56#endif 57 OutputDebugString( TRACE_TAG ); 58 OutputDebugString( szbuffer ); 59 } 60#ifdef __REACTOS__ 61 va_end(marker); 62#endif 63 64 return rc; 65} 66 67int filter(unsigned int code) 68{ 69 DbgP((L"####Got exception %u\n", code)); 70 return EXCEPTION_CONTINUE_SEARCH; 71} 72 73DWORD 74OpenSharedMemory( 75 PHANDLE phMutex, 76 PHANDLE phMemory, 77 PVOID *pMemory) 78/*++ 79 80Routine Description: 81 82 This routine opens the shared memory for exclusive manipulation 83 84Arguments: 85 86 phMutex - the mutex handle 87 88 phMemory - the memory handle 89 90 pMemory - a ptr. to the shared memory which is set if successful 91 92Return Value: 93 94 WN_SUCCESS -- if successful 95 96--*/ 97{ 98 DWORD dwStatus; 99 100 *phMutex = 0; 101 *phMemory = 0; 102 *pMemory = NULL; 103 104 *phMutex = CreateMutex(NULL, FALSE, TEXT(NFS41NP_MUTEX_NAME)); 105 if (*phMutex == NULL) 106 { 107 dwStatus = GetLastError(); 108 DbgP((TEXT("OpenSharedMemory: OpenMutex failed\n"))); 109 goto OpenSharedMemoryAbort1; 110 } 111 112 WaitForSingleObject(*phMutex, INFINITE); 113 114 *phMemory = OpenFileMapping(FILE_MAP_WRITE, 115 FALSE, 116 TEXT(NFS41_USER_SHARED_MEMORY_NAME)); 117 if (*phMemory == NULL) 118 { 119 dwStatus = GetLastError(); 120 DbgP((TEXT("OpenSharedMemory: OpenFileMapping failed\n"))); 121 goto OpenSharedMemoryAbort2; 122 } 123 124 *pMemory = MapViewOfFile(*phMemory, FILE_MAP_WRITE, 0, 0, 0); 125 if (*pMemory == NULL) 126 { 127 dwStatus = GetLastError(); 128 DbgP((TEXT("OpenSharedMemory: MapViewOfFile failed\n"))); 129 goto OpenSharedMemoryAbort3; 130 } 131 132 return ERROR_SUCCESS; 133 134OpenSharedMemoryAbort3: 135 CloseHandle(*phMemory); 136 137OpenSharedMemoryAbort2: 138 ReleaseMutex(*phMutex); 139 CloseHandle(*phMutex); 140 *phMutex = NULL; 141 142OpenSharedMemoryAbort1: 143 DbgP((TEXT("OpenSharedMemory: return dwStatus: %d\n"), dwStatus)); 144 145 return dwStatus; 146} 147 148VOID 149CloseSharedMemory( 150 PHANDLE hMutex, 151 PHANDLE hMemory, 152 PVOID *pMemory) 153/*++ 154 155Routine Description: 156 157 This routine relinquishes control of the shared memory after exclusive 158 manipulation 159 160Arguments: 161 162 hMutex - the mutex handle 163 164 hMemory - the memory handle 165 166 pMemory - a ptr. to the shared memory which is set if successful 167 168Return Value: 169 170--*/ 171{ 172 if (*pMemory) 173 { 174 UnmapViewOfFile(*pMemory); 175 *pMemory = NULL; 176 } 177 if (*hMemory) 178 { 179 CloseHandle(*hMemory); 180 *hMemory = 0; 181 } 182 if (*hMutex) 183 { 184 if (ReleaseMutex(*hMutex) == FALSE) 185 { 186 DbgP((TEXT("CloseSharedMemory: ReleaseMutex error: %d\n"), GetLastError())); 187 } 188 CloseHandle(*hMutex); 189 *hMutex = 0; 190 } 191} 192 193static DWORD StoreConnectionInfo( 194 IN LPCWSTR LocalName, 195 IN LPCWSTR ConnectionName, 196 IN USHORT ConnectionNameLength, 197 IN LPNETRESOURCE lpNetResource) 198{ 199 DWORD status; 200 HANDLE hMutex, hMemory; 201 PNFS41NP_SHARED_MEMORY pSharedMemory; 202 PNFS41NP_NETRESOURCE pNfs41NetResource; 203 INT Index; 204 BOOLEAN FreeEntryFound = FALSE; 205 206#ifdef __REACTOS__ 207 status = OpenSharedMemory(&hMutex, &hMemory, (PVOID *)&pSharedMemory); 208#else 209 status = OpenSharedMemory(&hMutex, &hMemory, &(PVOID)pSharedMemory); 210#endif 211 if (status) 212 goto out; 213 214 DbgP((TEXT("StoreConnectionInfo: NextIndex %d, NumResources %d\n"), 215 pSharedMemory->NextAvailableIndex, 216 pSharedMemory->NumberOfResourcesInUse)); 217 218 for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++) 219 { 220 if (!pSharedMemory->NetResources[Index].InUse) 221 { 222 FreeEntryFound = TRUE; 223 DbgP((TEXT("Reusing existing index %d\n"), Index)); 224 break; 225 } 226 } 227 228 if (!FreeEntryFound) 229 { 230 if (pSharedMemory->NextAvailableIndex >= NFS41NP_MAX_DEVICES) { 231 status = WN_NO_MORE_DEVICES; 232 goto out_close; 233 } 234 Index = pSharedMemory->NextAvailableIndex++; 235 DbgP((TEXT("Using new index %d\n"), Index)); 236 } 237 238 pSharedMemory->NumberOfResourcesInUse += 1; 239 240 pNfs41NetResource = &pSharedMemory->NetResources[Index]; 241 242 pNfs41NetResource->InUse = TRUE; 243 pNfs41NetResource->dwScope = lpNetResource->dwScope; 244 pNfs41NetResource->dwType = lpNetResource->dwType; 245 pNfs41NetResource->dwDisplayType = lpNetResource->dwDisplayType; 246 pNfs41NetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE; 247 pNfs41NetResource->LocalNameLength = (USHORT)(wcslen(LocalName) + 1) * sizeof(WCHAR); 248 pNfs41NetResource->RemoteNameLength = (USHORT)(wcslen(lpNetResource->lpRemoteName) + 1) * sizeof(WCHAR); 249 pNfs41NetResource->ConnectionNameLength = ConnectionNameLength; 250 251 StringCchCopy(pNfs41NetResource->LocalName, 252 pNfs41NetResource->LocalNameLength, 253 LocalName); 254 StringCchCopy(pNfs41NetResource->RemoteName, 255 pNfs41NetResource->RemoteNameLength, 256 lpNetResource->lpRemoteName); 257 StringCchCopy(pNfs41NetResource->ConnectionName, 258 pNfs41NetResource->ConnectionNameLength, 259 ConnectionName); 260 261 // TODO: copy mount options -cbodley 262 263out_close: 264#ifdef __REACTOS__ 265 CloseSharedMemory(&hMutex, &hMemory, (PVOID *)&pSharedMemory); 266#else 267 CloseSharedMemory(&hMutex, &hMemory, &(PVOID)pSharedMemory); 268#endif 269out: 270 return status; 271} 272 273ULONG 274SendTo_NFS41Driver( 275 IN ULONG IoctlCode, 276 IN PVOID InputDataBuf, 277 IN ULONG InputDataLen, 278 IN PVOID OutputDataBuf, 279 IN PULONG pOutputDataLen) 280{ 281 HANDLE DeviceHandle; // The mini rdr device handle 282 BOOL rc = FALSE; 283 ULONG Status; 284 285 Status = WN_SUCCESS; 286 DbgP((L"[aglo] calling CreateFile\n")); 287 DeviceHandle = CreateFile( 288 NFS41_USER_DEVICE_NAME, 289 GENERIC_READ | GENERIC_WRITE, 290 FILE_SHARE_READ | FILE_SHARE_WRITE, 291 (LPSECURITY_ATTRIBUTES)NULL, 292 OPEN_EXISTING, 293 0, 294 (HANDLE) NULL ); 295 296 DbgP((L"[aglo] after CreateFile Device Handle\n")); 297 if ( INVALID_HANDLE_VALUE != DeviceHandle ) 298 { 299 _SEH2_TRY { 300 DbgP((L"[aglo] calling DeviceIoControl\n")); 301 rc = DeviceIoControl( 302 DeviceHandle, 303 IoctlCode, 304 InputDataBuf, 305 InputDataLen, 306 OutputDataBuf, 307 *pOutputDataLen, 308 pOutputDataLen, 309 NULL ); 310 } _SEH2_EXCEPT(_SEH2_GetExceptionCode()) { 311 DbgP((L"#### In except\n")); 312 } _SEH2_END; 313 DbgP((L"[aglo] returned from DeviceIoControl %08lx\n", rc)); 314 if ( !rc ) 315 { 316 DbgP((L"[aglo] SendTo_NFS41Driver: returning error from DeviceIoctl\n")); 317 Status = GetLastError( ); 318 } 319 else 320 { 321 DbgP((L"[aglo] SendTo_NFS41Driver: The DeviceIoctl call succeded\n")); 322 } 323 CloseHandle(DeviceHandle); 324 } 325 else 326 { 327 Status = GetLastError( ); 328 DbgP((L"[aglo] SendTo_NFS41Driver: error %08lx opening device \n", Status)); 329 } 330 DbgP((L"[aglo] returned from SendTo_NFS41Driver %08lx\n", Status)); 331 return Status; 332} 333 334DWORD APIENTRY 335NPGetCaps( 336 DWORD nIndex ) 337{ 338 DWORD rc = 0; 339 340#ifndef __REACTOS__ 341 DbgP(( L"[aglo] GetNetCaps %d\n", nIndex )); 342#endif 343 switch ( nIndex ) 344 { 345 case WNNC_SPEC_VERSION: 346 rc = WNNC_SPEC_VERSION51; 347 break; 348 349 case WNNC_NET_TYPE: 350 rc = WNNC_NET_RDR2SAMPLE; 351 break; 352 353 case WNNC_DRIVER_VERSION: 354 rc = WNNC_DRIVER(1, 0); 355 break; 356 357 case WNNC_CONNECTION: 358 rc = WNNC_CON_GETCONNECTIONS | 359 WNNC_CON_CANCELCONNECTION | 360 WNNC_CON_ADDCONNECTION | 361 WNNC_CON_ADDCONNECTION3; 362 break; 363 364 case WNNC_ENUMERATION: 365 rc = WNNC_ENUM_LOCAL; 366 break; 367 368 case WNNC_START: 369 rc = 1; 370 break; 371 372 case WNNC_USER: 373 case WNNC_DIALOG: 374 case WNNC_ADMIN: 375 default: 376 rc = 0; 377 break; 378 } 379 380 return rc; 381} 382 383DWORD APIENTRY 384NPLogonNotify( 385 __in PLUID lpLogonId, 386 __in PCWSTR lpAuthentInfoType, 387 __in PVOID lpAuthentInfo, 388 __in PCWSTR lpPreviousAuthentInfoType, 389 __in PVOID lpPreviousAuthentInfo, 390 __in PWSTR lpStationName, 391 __in PVOID StationHandle, 392 __out PWSTR *lpLogonScript) 393{ 394 *lpLogonScript = NULL; 395 DbgP(( L"[aglo] NPLogonNotify: returning WN_SUCCESS\n" )); 396 return WN_SUCCESS; 397} 398 399DWORD APIENTRY 400NPPasswordChangeNotify ( 401 __in LPCWSTR lpAuthentInfoType, 402 __in LPVOID lpAuthentInfo, 403 __in LPCWSTR lpPreviousAuthentInfoType, 404 __in LPVOID lpPreviousAuthentInfo, 405 __in LPWSTR lpStationName, 406 LPVOID StationHandle, 407 DWORD dwChangeInfo ) 408{ 409 DbgP(( L"[aglo] NPPasswordChangeNotify: WN_NOT_SUPPORTED\n" )); 410 SetLastError( WN_NOT_SUPPORTED ); 411 return WN_NOT_SUPPORTED; 412} 413 414#ifdef __REACTOS__ 415DWORD APIENTRY 416NPAddConnection3( 417 __in HWND hwndOwner, 418 __in LPNETRESOURCE lpNetResource, 419 __in_opt LPWSTR lpPassword, 420 __in_opt LPWSTR lpUserName, 421 __in DWORD dwFlags); 422#endif 423 424DWORD APIENTRY 425NPAddConnection( 426 __in LPNETRESOURCE lpNetResource, 427 __in_opt LPWSTR lpPassword, 428 __in_opt LPWSTR lpUserName ) 429{ 430 return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 ); 431} 432 433DWORD APIENTRY 434NPAddConnection3( 435 __in HWND hwndOwner, 436 __in LPNETRESOURCE lpNetResource, 437 __in_opt LPWSTR lpPassword, 438 __in_opt LPWSTR lpUserName, 439 __in DWORD dwFlags) 440{ 441 DWORD Status; 442 WCHAR wszScratch[128]; 443 WCHAR LocalName[3]; 444 DWORD CopyBytes = 0; 445 CONNECTION_INFO Connection; 446 LPWSTR ConnectionName; 447 WCHAR ServerName[MAX_PATH]; 448 PWCHAR p; 449 DWORD i; 450 451 DbgP(( L"[aglo] NPAddConnection3('%s', '%s')\n", 452 lpNetResource->lpLocalName, lpNetResource->lpRemoteName )); 453 DbgP(( L"[aglo] username = '%s', passwd = '%s'\n", lpUserName, lpPassword)); 454 455 Status = InitializeConnectionInfo(&Connection, 456 (PMOUNT_OPTION_BUFFER)lpNetResource->lpComment, 457 &ConnectionName); 458 if (Status) { 459 DbgP(( L"InitializeConnectionInfo failed with %d\n", Status )); 460 goto out; 461 } 462 463 // \device\miniredirector\;<DriveLetter>:\Server\Share 464 465 // local name, must start with "X:" 466 if (lstrlen(lpNetResource->lpLocalName) < 2 || 467 lpNetResource->lpLocalName[1] != L':') { 468 Status = WN_BAD_LOCALNAME; 469 goto out; 470 } 471 472 LocalName[0] = (WCHAR) toupper(lpNetResource->lpLocalName[0]); 473 LocalName[1] = L':'; 474 LocalName[2] = L'\0'; 475 StringCchCopyW( ConnectionName, MAX_PATH, NFS41_DEVICE_NAME ); 476 StringCchCatW( ConnectionName, MAX_PATH, L"\\;" ); 477 StringCchCatW( ConnectionName, MAX_PATH, LocalName ); 478 479 // remote name, must start with "\\" 480 if (lpNetResource->lpRemoteName[0] == L'\0' || 481 lpNetResource->lpRemoteName[0] != L'\\' || 482 lpNetResource->lpRemoteName[1] != L'\\') { 483 Status = WN_BAD_NETNAME; 484 goto out; 485 } 486 487 /* note: remotename comes as \\server but we need to add \server thus +1 pointer */ 488 p = lpNetResource->lpRemoteName + 1; 489 ServerName[0] = L'\\'; 490 i = 1; 491 for(;;) { 492 /* convert servername ending unix slash to windows slash */ 493 if (p[i] == L'/') 494 p[i] = L'\\'; 495 /* deal with servername ending with any slash */ 496 if (p[i] == L'\0') 497 p[i] = L'\\'; 498 ServerName[i] = p[i]; 499 if (p[i] == L'\\') break; 500 i++; 501 } 502 ServerName[i] = L'\0'; 503 StringCchCatW( ConnectionName, MAX_PATH, ServerName); 504 /* insert the "nfs4" in between the server name and the path, 505 * just to make sure all calls to our driver come thru this */ 506 StringCchCatW( ConnectionName, MAX_PATH, L"\\nfs4" ); 507 508#ifdef CONVERT_2_UNIX_SLASHES 509 /* convert all windows slashes to unix slashes */ 510 { 511 PWCHAR q = p; 512 DWORD j = 0; 513 for(;;) { 514 if(q[j] == L'\0') break; 515 if (q[j] == L'\\') q[j] = L'/'; 516 j++; 517 } 518 } 519#else 520 /* convert all unix slashes to windows slashes */ 521 { 522 PWCHAR q = p; 523 DWORD j = 0; 524 for(;;) { 525 if(q[j] == L'\0') break; 526 if (q[j] == L'/') q[j] = L'\\'; 527 j++; 528 } 529 } 530#endif 531 StringCchCatW( ConnectionName, MAX_PATH, &p[i]); 532 DbgP(( L"[aglo] Full Connect Name: %s\n", ConnectionName )); 533 DbgP(( L"[aglo] Full Connect Name Length: %d %d\n", 534 (wcslen(ConnectionName) + 1) * sizeof(WCHAR), 535 (lstrlen(ConnectionName) + 1) * sizeof(WCHAR))); 536 537 if ( QueryDosDevice( LocalName, wszScratch, 128 ) 538 || GetLastError() != ERROR_FILE_NOT_FOUND) { 539 Status = WN_ALREADY_CONNECTED; 540 goto out; 541 } 542 543 MarshalConnectionInfo(&Connection); 544 545 Status = SendTo_NFS41Driver( IOCTL_NFS41_ADDCONN, 546 Connection.Buffer, Connection.BufferSize, 547 NULL, &CopyBytes ); 548 if (Status) { 549 DbgP(( L"[aglo] SendTo_NFS41Driver failed with %d\n", Status)); 550 goto out; 551 } 552 553 DbgP(( L"[aglo] calling DefineDosDevice\n")); 554 if ( !DefineDosDevice( DDD_RAW_TARGET_PATH | 555 DDD_NO_BROADCAST_SYSTEM, 556 lpNetResource->lpLocalName, 557 ConnectionName ) ) { 558 Status = GetLastError(); 559 DbgP(( L"[aglo] DefineDosDevice failed with %d\n", Status)); 560 goto out_delconn; 561 } 562 563 // The connection was established and the local device mapping 564 // added. Include this in the list of mapped devices. 565 Status = StoreConnectionInfo(LocalName, ConnectionName, 566 Connection.Buffer->NameLength, lpNetResource); 567 if (Status) { 568 DbgP(( L"[aglo] StoreConnectionInfo failed with %d\n", Status)); 569 goto out_undefine; 570 } 571 572out: 573 FreeConnectionInfo(&Connection); 574 DbgP(( L"[aglo] NPAddConnection3: status %08X\n", Status)); 575 return Status; 576out_undefine: 577 DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | 578 DDD_EXACT_MATCH_ON_REMOVE, LocalName, ConnectionName); 579out_delconn: 580 SendTo_NFS41Driver(IOCTL_NFS41_DELCONN, ConnectionName, 581 Connection.Buffer->NameLength, NULL, &CopyBytes); 582 goto out; 583} 584 585DWORD APIENTRY 586NPCancelConnection( 587 __in LPWSTR lpName, 588 __in BOOL fForce ) 589{ 590 DWORD Status = 0; 591 592 HANDLE hMutex, hMemory; 593 PNFS41NP_SHARED_MEMORY pSharedMemory; 594 595 DbgP((TEXT("NPCancelConnection\n"))); 596 DbgP((TEXT("NPCancelConnection: ConnectionName: %S\n"), lpName)); 597 598 Status = OpenSharedMemory( &hMutex, 599 &hMemory, 600 (PVOID)&pSharedMemory); 601 602 if (Status == WN_SUCCESS) 603 { 604 INT Index; 605 PNFS41NP_NETRESOURCE pNetResource; 606 Status = WN_NOT_CONNECTED; 607 608 DbgP((TEXT("NPCancelConnection: NextIndex %d, NumResources %d\n"), 609 pSharedMemory->NextAvailableIndex, 610 pSharedMemory->NumberOfResourcesInUse)); 611 612 for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++) 613 { 614 pNetResource = &pSharedMemory->NetResources[Index]; 615 616 if (pNetResource->InUse) 617 { 618 if ( ( (wcslen(lpName) + 1) * sizeof(WCHAR) == 619 pNetResource->LocalNameLength) 620 && ( !wcscmp(lpName, pNetResource->LocalName) )) 621 { 622 ULONG CopyBytes; 623 624 DbgP((TEXT("NPCancelConnection: Connection Found:\n"))); 625 626 CopyBytes = 0; 627 628 Status = SendTo_NFS41Driver( IOCTL_NFS41_DELCONN, 629 pNetResource->ConnectionName, 630 pNetResource->ConnectionNameLength, 631 NULL, 632 &CopyBytes ); 633 634 if (Status != WN_SUCCESS) 635 { 636 DbgP((TEXT("NPCancelConnection: SendToMiniRdr returned Status %lx\n"),Status)); 637 break; 638 } 639 640 if (DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE, 641 lpName, 642 pNetResource->ConnectionName) == FALSE) 643 { 644 DbgP((TEXT("RemoveDosDevice: DefineDosDevice error: %d\n"), GetLastError())); 645 Status = GetLastError(); 646 } 647 else 648 { 649 pNetResource->InUse = FALSE; 650 pSharedMemory->NumberOfResourcesInUse--; 651 652 if (Index+1 == pSharedMemory->NextAvailableIndex) 653 pSharedMemory->NextAvailableIndex--; 654 } 655 break; 656 } 657 658 DbgP((TEXT("NPCancelConnection: Name %S EntryName %S\n"), 659 lpName,pNetResource->LocalName)); 660#ifndef __REACTOS__ 661 DbgP((TEXT("NPCancelConnection: Name Length %d Entry Name Length %d\n"), 662 pNetResource->LocalNameLength,pNetResource->LocalName)); 663#else 664 DbgP((TEXT("NPCancelConnection: Name Length %d Entry Name Length %d\n"), 665 (wcslen(lpName) + 1) * sizeof(WCHAR), pNetResource->LocalNameLength)); 666#endif 667 668 } 669 } 670 671 CloseSharedMemory( &hMutex, 672 &hMemory, 673 (PVOID)&pSharedMemory); 674 } 675 676 return Status; 677} 678 679DWORD APIENTRY 680NPGetConnection( 681 __in LPWSTR lpLocalName, 682 __out_bcount(*lpBufferSize) LPWSTR lpRemoteName, 683 __inout LPDWORD lpBufferSize ) 684{ 685 DWORD Status = 0; 686 687 HANDLE hMutex, hMemory; 688 PNFS41NP_SHARED_MEMORY pSharedMemory; 689 690 Status = OpenSharedMemory( &hMutex, 691 &hMemory, 692 (PVOID)&pSharedMemory); 693 694 if (Status == WN_SUCCESS) 695 { 696 INT Index; 697 PNFS41NP_NETRESOURCE pNetResource; 698 Status = WN_NOT_CONNECTED; 699 700 for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++) 701 { 702 pNetResource = &pSharedMemory->NetResources[Index]; 703 704 if (pNetResource->InUse) 705 { 706 if ( ( (wcslen(lpLocalName) + 1) * sizeof(WCHAR) == 707 pNetResource->LocalNameLength) 708 && ( !wcscmp(lpLocalName, pNetResource->LocalName) )) 709 { 710 if (*lpBufferSize < pNetResource->RemoteNameLength) 711 { 712 *lpBufferSize = pNetResource->RemoteNameLength; 713 Status = WN_MORE_DATA; 714 } 715 else 716 { 717 *lpBufferSize = pNetResource->RemoteNameLength; 718 CopyMemory( lpRemoteName, 719 pNetResource->RemoteName, 720 pNetResource->RemoteNameLength); 721 Status = WN_SUCCESS; 722 } 723 break; 724 } 725 } 726 } 727 728 CloseSharedMemory( &hMutex, &hMemory, (PVOID)&pSharedMemory); 729 } 730 731 return Status; 732} 733 734DWORD APIENTRY 735NPOpenEnum( 736 DWORD dwScope, 737 DWORD dwType, 738 DWORD dwUsage, 739 LPNETRESOURCE lpNetResource, 740 LPHANDLE lphEnum ) 741{ 742 DWORD Status; 743 744 DbgP((L"[aglo] NPOpenEnum\n")); 745 746 *lphEnum = NULL; 747 748 switch ( dwScope ) 749 { 750 case RESOURCE_CONNECTED: 751 { 752 *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( ULONG ) ); 753 754 if (*lphEnum ) 755 { 756 Status = WN_SUCCESS; 757 } 758 else 759 { 760 Status = WN_OUT_OF_MEMORY; 761 } 762 break; 763 } 764 break; 765 766 case RESOURCE_CONTEXT: 767 default: 768 Status = WN_NOT_SUPPORTED; 769 break; 770 } 771 772 773 DbgP((L"[aglo] NPOpenEnum returning Status %lx\n",Status)); 774 775 return(Status); 776} 777 778DWORD APIENTRY 779NPEnumResource( 780 HANDLE hEnum, 781 LPDWORD lpcCount, 782 LPVOID lpBuffer, 783 LPDWORD lpBufferSize) 784{ 785 DWORD Status = WN_SUCCESS; 786 ULONG EntriesCopied; 787 LPNETRESOURCE pNetResource; 788 ULONG SpaceNeeded = 0; 789 ULONG SpaceAvailable; 790 PWCHAR StringZone; 791 HANDLE hMutex, hMemory; 792 PNFS41NP_SHARED_MEMORY pSharedMemory; 793 PNFS41NP_NETRESOURCE pNfsNetResource; 794 INT Index = *(PULONG)hEnum; 795 796 797 DbgP((L"[aglo] NPEnumResource\n")); 798 799 DbgP((L"[aglo] NPEnumResource Count Requested %d\n", *lpcCount)); 800 801 pNetResource = (LPNETRESOURCE) lpBuffer; 802 SpaceAvailable = *lpBufferSize; 803 EntriesCopied = 0; 804 StringZone = (PWCHAR) ((PBYTE)lpBuffer + *lpBufferSize); 805 806 Status = OpenSharedMemory( &hMutex, 807 &hMemory, 808 (PVOID)&pSharedMemory); 809 810 if ( Status == WN_SUCCESS) 811 { 812 Status = WN_NO_MORE_ENTRIES; 813 for (Index = *(PULONG)hEnum; EntriesCopied < *lpcCount && 814 Index < pSharedMemory->NextAvailableIndex; Index++) 815 { 816 pNfsNetResource = &pSharedMemory->NetResources[Index]; 817 818 if (pNfsNetResource->InUse) 819 { 820 SpaceNeeded = sizeof( NETRESOURCE ); 821 SpaceNeeded += pNfsNetResource->LocalNameLength; 822 SpaceNeeded += pNfsNetResource->RemoteNameLength; 823 SpaceNeeded += 5 * sizeof(WCHAR); // comment 824 SpaceNeeded += sizeof(NFS41_PROVIDER_NAME_U); // provider name 825 if ( SpaceNeeded > SpaceAvailable ) 826 { 827 Status = WN_MORE_DATA; 828 DbgP((L"[aglo] NPEnumResource More Data Needed - %d\n", SpaceNeeded)); 829 *lpBufferSize = SpaceNeeded; 830 break; 831 } 832 else 833 { 834 SpaceAvailable -= SpaceNeeded; 835 836 pNetResource->dwScope = pNfsNetResource->dwScope; 837 pNetResource->dwType = pNfsNetResource->dwType; 838 pNetResource->dwDisplayType = pNfsNetResource->dwDisplayType; 839 pNetResource->dwUsage = pNfsNetResource->dwUsage; 840 841 // setup string area at opposite end of buffer 842 SpaceNeeded -= sizeof( NETRESOURCE ); 843 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded ); 844 // copy local name 845 StringCchCopy( StringZone, 846 pNfsNetResource->LocalNameLength, 847 pNfsNetResource->LocalName ); 848 pNetResource->lpLocalName = StringZone; 849 StringZone += pNfsNetResource->LocalNameLength/sizeof(WCHAR); 850 // copy remote name 851 StringCchCopy( StringZone, 852 pNfsNetResource->RemoteNameLength, 853 pNfsNetResource->RemoteName ); 854 pNetResource->lpRemoteName = StringZone; 855 StringZone += pNfsNetResource->RemoteNameLength/sizeof(WCHAR); 856 // copy comment 857 pNetResource->lpComment = StringZone; 858 *StringZone++ = L'A'; 859 *StringZone++ = L'_'; 860 *StringZone++ = L'O'; 861 *StringZone++ = L'K'; 862 *StringZone++ = L'\0'; 863 // copy provider name 864 pNetResource->lpProvider = StringZone; 865 StringCbCopyW( StringZone, sizeof(NFS41_PROVIDER_NAME_U), NFS41_PROVIDER_NAME_U ); 866 StringZone += sizeof(NFS41_PROVIDER_NAME_U)/sizeof(WCHAR); 867 EntriesCopied++; 868 // set new bottom of string zone 869 StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded ); 870 Status = WN_SUCCESS; 871 } 872 pNetResource++; 873 } 874 } 875 CloseSharedMemory( &hMutex, &hMemory, (PVOID*)&pSharedMemory); 876 } 877 878 *lpcCount = EntriesCopied; 879 *(PULONG) hEnum = Index; 880 881 DbgP((L"[aglo] NPEnumResource entries returned: %d\n", EntriesCopied)); 882 883 return Status; 884} 885 886DWORD APIENTRY 887NPCloseEnum( 888 HANDLE hEnum ) 889{ 890 DbgP((L"[aglo] NPCloseEnum\n")); 891 HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum ); 892 return WN_SUCCESS; 893} 894 895DWORD APIENTRY 896NPGetResourceParent( 897 LPNETRESOURCE lpNetResource, 898 LPVOID lpBuffer, 899 LPDWORD lpBufferSize ) 900{ 901 DbgP(( L"[aglo] NPGetResourceParent: WN_NOT_SUPPORTED\n" )); 902 return WN_NOT_SUPPORTED; 903} 904 905DWORD APIENTRY 906NPGetResourceInformation( 907 __in LPNETRESOURCE lpNetResource, 908 __out_bcount(*lpBufferSize) LPVOID lpBuffer, 909 __inout LPDWORD lpBufferSize, 910 __deref_out LPWSTR *lplpSystem ) 911{ 912 DbgP(( L"[aglo] NPGetResourceInformation: WN_NOT_SUPPORTED\n" )); 913 return WN_NOT_SUPPORTED; 914} 915 916DWORD APIENTRY 917NPGetUniversalName( 918 LPCWSTR lpLocalPath, 919 DWORD dwInfoLevel, 920 LPVOID lpBuffer, 921 LPDWORD lpBufferSize ) 922{ 923 DbgP(( L"[aglo] NPGetUniversalName: WN_NOT_SUPPORTED\n" )); 924 return WN_NOT_SUPPORTED; 925}