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