Problem with Win32 WNet APIs and NFS paths - winapi

I am running on a Win2K8R2 system that has Microsoft's NFS client installed in addition to the Windows CIFS client.
Given a UNC path (which the NFS client does support with caveats) I need to be able to tell if operations on the path would be handled by the CIFS or NFS client. WNetGetResourceInformation() would seem to provide this, but I have not been able to get it to work when the UNC path is to an NFS server.
Sample code:
int GetResourceInformation(TCHAR* path, void* buffer, DWORD* size)
{
TCHAR* p = NULL;
NETRESOURCE nr;
memset(&nr, 0, sizeof(nr));
nr.lpRemoteName = path;
DWORD dwRetVal = WNetGetResourceInformation(&nr, buffer, size, &p);
if(dwRetVal == NO_ERROR)
{
NETRESOURCE* tmp = (NETRESOURCE*)buffer;
wprintf(L"%s provider=%s system=%s\n", path, tmp->lpProvider, (p == NULL) ? L"<null>" : p);
}
else
{
wprintf(L"WNetGetResourceInformation failed for %s with error: %u\n", path, dwRetVal);
}
return dwRetVal;
}
I have also tried filling in the NETRESOURCE lpProvider and/or dwType fields as suggested in the doc but with no change in behavior.
If I pass the function a CIFS UNC path it succeeds. If I pass it an NFS UNC path it fails with error 487 "Attempt to access invalid address.". I also tried passing the native NFS path style hostname:/export/file but this fails with error 67 "The network name cannot be found."
I found the following sample for using WNetAddConnection2() with NFS but this code also fails for me with error 50 "The request is not supported". I can successfully mount the export using either "net use" command or the NFS-specific mount.exe tool provided by Microsoft.
Finally, WNetOpenEnum/WNetEnumResource does not return any NFS provider information for me or even show any connected drives that I have mapped via "net use" or mount.exe.
My general question is, has anyone had better success using the the WNet APIs with the NFS provider? Specifically, is there some mechanism I can use to determine the provider for a remote path?

Are you building as x86 or x64? It looks like the WNet* API's don't work correctly for NFS shares from an x86 process under WOW64. You can see this without writing code - if you have an NFS share mounted, "C:\windows\system32\net use" will show it, where "C:\windows\syswow64\net use" will not. Filesystem access seems OK the 32-bit process, but none of the APIs work.
Even built as x64, using a NULL lpProvider is inconsistent for me. Half the time it doesn't work, the other half it waits about 5 seconds before returning.
Calling WNetGetResourceInformation twice, once with a lpProvider of "NFS Network" and once with "Microsoft Windows Network" works consistently and returns instantly.

Related

Golang MSI can't see mounted drives on windows

So I have an windows msi installer that I created by cross compiling from a golang program and installed on a client windows machine. The program sends data out from a folder on the windows machine to a Kinesis stream. The program works fine for all files and folders on the local C:\ drive.
My issue is that when the client is using a mounted NTFS drive ("I://, J://, D://") I get an error message with
level=info msg="Ignoring target I:\\xml with invalid stat: open I:\\xml: The system cannot find the path specified."
No matter the mounted drive (E,F,G, etc) I get the same error message.
I've tried this across multiple clients and received the same error.
So just for background- I'm compiling the program using wine to get it to an msi when building. The program is taking on a SYSTEM USER role and I've already checked permissions on the mounted directories (and made them wide open- still no luck). Been banging my head against the wall over this one for a while so the question is: has anyone else had an issue like this?
Don't know how much this will help but here is the specific portion of GO code I'm using:
p, err := filepath.Abs(t.Path)
if err != nil {
Logger.Infof("Ignoring invalid target path: %s, error: %s", t.Path, err)
continue
}
_, err = os.Lstat(t.Path)
if err != nil {
Logger.Infof("Ignoring target %s with invalid stat: %s", t.Path, err)
continue
}
c.targets = append(c.targets, site.WatchTarget{p, t.SrcTag})
I've tried os.Stat, Lstat and even os.Open to no avail. Just about at the end of my tether on this one.
The ideal result would be a suggestion on any changes you could suggest that would allow a system user from a cross compiled go program to see mounted network drives.

KMDF WdfDriverCreate function returns "insufficient resources"

I'm trying to write a kmdf driver to target a custom PCIe board. On following the default project that Microsoft provides, I made a few minor changes to the .inf file, mainly changing the names of strings and providing the hardware ID of our PCIe board.
Deploying the driver works as it should. The driver installs and shows up on the device manager, but it says that it didn't install correctly or it may be corrupted.
On debugging, I see that WdfDriverCreate fails with an error of 0xC000009A, which means insufficient resources.
For reference, this is the generated code that the kmdf template project makes for you, which is what I am currently running:
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING( DriverObject, RegistryPath );
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
//
// Register a cleanup callback so that we can call WPP_CLEANUP when
// the framework driver object is deleted during driver unload.
//
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
attributes.EvtCleanupCallback = CIPDriverEvtDriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(&config,
CIPDriverEvtDeviceAdd
);
KdPrint(("CIP: Driver Entry\n"));
status = WdfDriverCreate(DriverObject,
RegistryPath,
&attributes,
&config,
WDF_NO_HANDLE
);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
KdPrint(("CIP: WdfDriverCreate failed with status - 0x%x\n", status));
WPP_CLEANUP(DriverObject);
return status;
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
return status;
}
My first question is, What would cause this?
I attempted to dump a log after the error is raised by running
!wdfkd.wdflogdump mydriver.sys
But it never works. I ensured that all symbol paths are loaded properly, as shown below
fffff880`05fdd000 fffff880`05fe6000 CIPDriver (private pdb symbols) C:\Users\jimmyjoebobby\Documents\Visual Studio 2013\Projects\CIPDriver\x64\Win7Debug\CIPDriver.pdb
22: kd> lm m wdf*
start end module name
fffff880`00e5e000 fffff880`00f20000 Wdf01000 (pdb symbols) c:\winsymbols\Wdf01000.pdb\03FC6AA4329F4372BE924775887225632\Wdf01000.pdb
fffff880`00f20000 fffff880`00f30000 WDFLDR (pdb symbols) c:\winsymbols\wdfldr.pdb\9674B20D2E5B4E7AA2DE143F642A176E2\wdfldr.pdb
Where "CIPDriver" is my driver.
On running the dump command, this is the output:
22: kd> !wdfkd.wdflogdump CIPDriver.sys
Trace searchpath is:
Trace format prefix is: %7!u!: %!FUNC! -
TMF file used for formatting log is: C:\WinDDK\7600.16385.1\tools\tracing\amd64\wdf01000.tmf
Log at fffffa80356232f8
Gather log: Please wait, this may take a moment (reading 0 bytes).
% read so far ...
warn: The log could not be accessed
hint: Are the symbols the WDF library available?
hint: The log is inaccessable after driver unload.
And the output of .sympath
22: kd> .sympath
Symbol search path is: C:\Users\jimmyjoebobby\Documents\Visual Studio 2013\Projects\CIPDriver\Win7Debug;C:\winsymbols
Expanded Symbol search path is: c:\users\jimmyjoebobby\documents\visual studio 2013\projects\cipdriver\win7debug;c:\winsymbols
Where C:\winsymbols is a cache of Microsofts's symbols which I acquired by following the guide here: https://msdn.microsoft.com/en-us/library/windows/hardware/ff558829(v=vs.85).aspx
My second question is, how do I correctly setup the debugger to dump out the logs?
Thanks
I don't quite understand why this helps, but if I turned off KMDF verifier under
[DriverName] Package -> Properties -> Configuration Properties -> Driver Install -> KMDF Verifier -> Enable KMDF Verifier
And deploy the driver, it works. If I turn that on, it fails. I deployed my driver a few times toggling that option on and off and it always fails when it's on.
I posted this question along with my findings. Maybe someone there could answer why this is the case: https://www.osronline.com/showthread.cfm?link=277793

win32 API SearchPath fails

The win32 API SearchPath API fails to find the "telnet.exe" binary path even though its present in system32.
However when I did a search for notepad.exe, with the same code it returns the file path. What puzzles me here is that both notepad.exe and telnet.exe lies in the same directory i.e C:\windows\system32.
This is the code I have written
char path[MAX_PATH] = {0};
LPSTR* ptr = NULL;
DWORD dwRet = SearchPathA(NULL, "telnet.exe",
NULL, MAX_PATH, (LPSTR)path, ptr);
This would always return 0 and the GetLastError is 2 ( File not found)
Any idea what is happening here?
I am using windows 2008 R2 enterprise edition on an x64 machine
Thanks & Regards
Sunil
It's not working because you application is 32 bit and is being affected by the File System Redirector. Your application is not looking in C:\Windows\System32 but is instead being redirected to C:\Windows\SysWow64.
notepad.exe exists in both System32 and SysWow64, but telnet.exe only exists in System32. So you application does not find it when it searches the path.
You can disable this behavior for your application by calling Wow64DisasbleWow64FsRedirection. But note the warnings in the documentation links that indicate that this should only be disabled temporarily and then re-enabled.

Java 7 WatchService does not generate events when registered directory is on a network drive

I know this was asked elsewhere a year ago but I'm looking for any updates please.
I have a program in Java 7 that uses WatchService to monitor a directory for new files being created there. If I register a directory on my local machine (e.g. c:\NewFiles) then all is fine. However when I try to get it to listen to a folder on a network drive it compiles and runs but exits straight away because it doesn't seem to get notified of any events.. here is just a fragment of my code...
private final WatchService watcher;
private final Map<WatchKey, Path> keys;
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<>();
I register the directory...
String srcDirPath = "G:\\NewFiles";
Path dir = Paths.get(srcDirPath);
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
keys.put(key, dir);
then at the end of the loop that checks for events...
if (keys.isEmpty()) {
System.out.println("Drive is inaccessible");
break;
}
Here I always get the "Drive is inaccessible" warning. I tried copying my Java files to this network directory and running them from there but I get the same problem.
Is it possible to run Watchservice like this from a local machine to listen to changes to a directory on a network drive? Am I getting a permission or firewall problem here? I am using Windows 7 and most likely the network drive is also on a Windows 7 machine.

Problem launching external executable from Win32 application

I am trying to launch an external application from within my Win32 application but it's failing. Following is the code I am using:
HINSTANCE instance = ShellExecute(NULL, _T("open"), _T("loader.exe"), NULL, NULL, SW_SHOWNORMAL);
if((int)instance <= 32)
{
_cprintf("Error = 0x%X\n", GetLastError());
return 0;
}
The instance value I get is 0x00000002 and GetLastError returns 0x2. The same code works when I try to launch other applications like iTunes.exe or cmd.exe. Does it has anything to do with external application? By the way, win32 application and loader.exe application are located in the same folder.
Any help would be highly appreciated.
Farooq-
Well, error 0x2 is ERROR_FILE_NOT_FOUND
Looks like it can't find "loader.exe"
Error 2 is "File not found":
http://msdn.microsoft.com/en-us/library/ms681382(v=vs.85).aspx
I'm guessing it can't find loader.exe.
Put loader.exe somewhere in the search path, or provide the full path. That is how to avoid this file not found error. Windows error codes are all documented on MSDN.

Resources