I'm printing using CreateDC, passing in a valid DEVMODE structure and getting NULL returned which indicates an error but GetLastError returns 0.
m_hDC = ::CreateDC(L"WINSPOOL", PrinterName, NULL, pDevMode);
if (m_hDC == NULL)
{
throw Exception(GetLastError(), __LINE__, _T(__FILE__));
}
This is working for all of my customers apart from one, any ideas?
This turned out to be a problem with the thunking spooler api's.
The software is a 32 bit Windows service running on a 64 bit system.
It seems that only one user/session can print at a time from a 32 bit process, the next user has to wait for splwow64.exe to timeout (or kill it) before they can print.
It is covered in a technote from MS.
Are you sure that pDevMode is valid? You could try using a NULL pointer here in case the DEVMODE is the issue.
Related
I am implementing a DNS cache in Windows†and I need to know how long to cache negative responses. RFC 2308 says to use the TTL of the SOA record I receive, but despite the SOA record being sent to me on the wire (as confirmed by tcpdump), DnsQuery will not expose it to me. For example, running the following C++ code gives me no output:
PDNS_RECORDA data = nullptr;
DNS_STATUS rv = dnsQuery("www.google.com", DNS_TYPE_SOA, DNS_QUERY_STANDARD,
nullptr, &data, nullptr);
if (data != nullptr) {
cout << "Yippee" << endl;
}
I have tried every value between 0 and 0xFF as the second argument, but never am I given a SOA record (though several other records come through fine such as A, AAAA, and CNAME). Does anyone know how to get it to behave?
The third parameter accepts various flags. I tried DNS_QUERY_RETURN_MESSAGE which looked promising, but seemed to have no visible effect (I am on Windows 7 so it should be supported per the docs). I also tried a variety of other flags in desperation. Namely DNS_QUERY_BYPASS_CACHE, DNS_QUERY_RETURN_MESSAGE | DNS_QUERY_BYPASS_CACHE, DNS_QUERY_WIRE_ONLY, and DNS_QUERY_DONT_RESET_TTL_VALUES. I have read through the entire list of query options and did not see anything else that looked terribly promising. Note that for each flag, I tried every value between 0 and 0xFF as the second argument, and looked for anything in the resulting list of type DNS_TYPE_SOA.
†I know Windows has a perfectly good DNS cache.
I have the problem . I am trying to get process memory usage , but unfortunatly some process always returning the same value in my case - 3276. How can I get the real amount of memory using by the process. Thanks in advance.
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
PROCESS_MEMORY_COUNTERS memCounter;
BOOL result = GetProcessMemoryInfo(hProcess,
&memCounter,
sizeof( memCounter ));
char procID[20];
char procMem[100];
sprintf_s(procMem, "%d",(memCounter.WorkingSetSize/1024/1024));
if (!(strcmp(procMem,"3276"))) {
strcpy(procMem, "<unavaliable>");
}
sprintf_s(procID, "%d",entry.th32ProcessID);
You are not checking the return values for errors. You simply must do that. Clearly one of them is failing. Is it OpenProcess, or is it GetProcessMemoryInfo? How can we tell without any error checking. Read the documentation for the function and follow the instructions there given to check for errors.
Once you identify which function is failing you can try to work out why. In case of failure, both of these functions will set the last error value and so you can call GetLastError to discern what went wrong.
Quite possibly OpenProcess is failing because you are asking for too many access rights. All you need is PROCESS_QUERY_INFORMATION | PROCESS_VM_READ. Another possible failure mode is that some system processes will not give up this information. Ultimately you need to perform error checking to diagnose the specific problem.
I'm messing around with some driver development and I'm having an issue getting some of my code to work. I'm not sure if it's a quirk with the API that I'm unaware of or what.
I have a user app that has created a named shared object under BaseNamedObjects with CreateFileMapping, MapViewOfFile, etc. I'm trying to read this shared object inside of my driver code using ZwOpenSection and ZwMapViewOfSection
The problem code is below:
char *sharedData = NULL;
SIZE_T vs = 256;
InitializeObjectAttributes(&myAttributes,§ionName,OBJ_KERNEL_HANDLE,NULL,NULL);
ZwOpenSection(§ionHandle,SECTION_MAP_READ,&myAttributes)
ZwMapViewOfSection(§ionHandle, ZwGetCurrentProcess(), (PVOID *)sharedData, 0, 256,
NULL, &vs, ViewUnmap, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
The call to ZwOpenSection completes successfully and I get the object properly, but the second call fails. The status returned says it's an issue with the ninth parameter, but I've tried every combination I could think of with nothing to show for it, so I'm not sure if it's an issue with a different parameter causing the 9th to be "incorrect" or if I'm missing something else
Thanks.
Is the access permission with which the section was created the same as the one you have passed here?
MEM_COMMIT is not allowed in a direct call in this function. If you still want to commit and reserve pages, try calling the virtualalloc(), otherwise just pass NULL in the 8th parameter.
I have a problem caused by a failure in Direct3D9::CreateDevice(). It fails when the following code is executed with a locked screen under Windows 7. Due to requirements, I need to be able to create a device while the screen is locked.
I get a D3DERR_INVALIDCALL error when CreateDevice is called with the following parameters. I've experimented extensively with the HWND being used, and double checked that it is valid. I've also tried out various tweaks to the presentation parameters to no avail. Anyone encountered this before or have a better idea of what might be causing the invalid call return?
Again, this failure only occurs with a locked screen, when run in any other tested state, it succeeds.
D3DPRESENT_PARAMETERS pp;
ZeroMemory( &pp, sizeof(D3DPRESENT_PARAMETERS) );
pp.BackBufferFormat = D3DFMT_UNKNOWN;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.Windowed = TRUE;
HWND focusWndHnd = GetConsoleWindow();
if ( focusWndHnd == NULL && pp.hDeviceWindow == NULL )
{
focusWndHnd = ::GetDesktopWindow();
}
IDirect3DDevice9* pd3dDevice;
IDirect3D9* pD3D = Direct3DCreate9( D3D_SDK_VERSION );
hr = pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, focusWndHnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE, &pp, &pd3dDevice );
The legacy Direct3D 9 interface considers the 'secure desktop' to be a lost device scenario. Use of a WDDM aware version of Direct3D (Direct3D9Ex, Direct3D 10.x, or Direct3D 11.x) will avoid this problem.
Could it be that you need a different value for BackBufferFormat different than D3DFMT_UNKNOWN, due to only windowed apps allowing that value, just like OJ stated here?
My memory is hazy, but I believe this is a known limitation ("by design") with D3D with respect to the lock screen (and running as a service).
Even if you could create the D3D device, you won't be able to draw on top of the lock screen. So you'll probably be better off designing your app such that it defers the D3D device creation until after the screen becomes unlocked.
Use WTSRegisterSessionNotification to register for notifications of when the screen becomes locked or unlocked.
Thanks to Chuck Walbourn's answer I have solved my related issue that the D3D Device initialization fails as soon the elevation prompt secure session is active. In my case I received a D3DERR_NOTAVAILABLE error during the secure session. Having replaced IDirect3D9* with IDirect3D9Ex* and Direct3DCreate9 with Direct3DCreate9Ex then initialization finished successfully!
Additionally I have to stress that Chuck's answer does not refer to Kent's answer directly but just to a related issue, since - as I have understood it right - Kent's scenario refers to the WTS_SESSIONSTATE_LOCK session that can be entered through CTRL+L. In Kent's case I haven't experienced a problem with the D3D initialization in a locked session.
I have a DLL that's loaded into a 3rd party parent process as an extension. From this DLL I instantiate external processes (my own) by using CreateProcess API. This works great in 99.999% of the cases but sometimes this suddenly fails and stops working permanently (maybe a restart of the parent process would solve this but this is undesirable and I don't want to recommend that until I solve the problem.) The failure is symptomized by external process not being invoked any more even though CreteProcess() doesn't report an error and by GetExitCodeProcess() returning 128. Here's the simplified version of what I'm doing:
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
if(!CreateProcess(
NULL, // No module name (use command line).
"<my command line>",
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
CREATE_SUSPENDED, // Create suspended.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
// Handle error.
}
else
{
// Do something.
// Resume the external process thread.
DWORD resumeThreadResult = ResumeThread(pi.hThread);
// ResumeThread() returns 1 which is OK
// (it means that the thread was suspended but then restarted)
// Wait for the external process to finish.
DWORD waitForSingelObjectResult = WaitForSingleObject(pi.hProcess, INFINITE);
// WaitForSingleObject() returns 0 which is OK.
// Get the exit code of the external process.
DWORD exitCode;
if(!GetExitCodeProcess(pi.hProcess, &exitCode))
{
// Handle error.
}
else
{
// There is no error but exitCode is 128, a value that
// doesn't exist in the external process (and even if it
// existed it doesn't matter as it isn't being invoked any more)
// Error code 128 is ERROR_WAIT_NO_CHILDREN which would make some
// sense *if* GetExitCodeProcess() returned FALSE and then I were to
// get ERROR_WAIT_NO_CHILDREN with GetLastError()
}
// PROCESS_INFORMATION handles for process and thread are closed.
}
External process can be manually invoked from Windows Explorer or command line and it starts just fine on its own. Invoked like that it, before doing any real work, creates a log file and logs some information about it. But invoked like described above this logging information doesn't appear at all so I'm assuming that the main thread of the external process never enters main() (I'm testing that assumption now.)
There is at least one thing I could do to try to circumvent the problem (not start the thread suspended) but I would first like to understand the root of the failure first. Does anyone has any idea what could cause this and how to fix it?
Quoting from the MSDN article on GetExitCodeProcess:
The following termination statuses can be returned if the process has terminated:
The exit value specified in the
ExitProcess or TerminateProcess
function
The return value from the
main or WinMain function of the
process
The exception value for an
unhandled exception that caused the
process to terminate
Given the scenario you described, I think the most likely cause ist the third: An unhandled exception. Have a look at the source of the processes you create.
Have a look at Desktop Heap memory.
Essentially the desktop heap issue comes down to exhausted resources (eg starting too many processes). When your app runs out of these resources, one of the symptoms is that you won't be able to start a new process, and the call to CreateProcess will fail with code 128.
Note that the context you run in also has some effect. For example, running as a service, you will run out of desktop heap much faster than if you're testing your code in a console app.
This post has a lot of good information about desktop heap
Microsoft Support also has some useful information.
There are 2 issues that i could think of from your code sample
1.Get yourusage of the first 2 paramaters to the creatprocess command working first. Hard code the paths and invoke notepad.exe and see if that comes up. keep tweaking this until you have notepad running.
2.Contrary to your comment, If you have passed the currentdirectory parameter for the new process as NULL, it will use the current working directory of the process to start the new process from and not the parent' starting directory.
I assume that your external process exe cannot start properly due to dll dependencies that cannot be resolved in the new path.
ps : In the debugger watch for #err,hr which will tell you the explanation for the last error code,