15,881,882 members
Sign in
Sign in
Email
Password
Forgot your password?
Sign in with
home
articles
Browse Topics
>
Latest Articles
Top Articles
Posting/Update Guidelines
Article Help Forum
Submit an article or tip
Import GitHub Project
Import your Blog
quick answers
Q&A
Ask a Question
View Unanswered Questions
View All Questions
View C# questions
View C++ questions
View Javascript questions
View Visual Basic questions
View Python questions
discussions
forums
CodeProject.AI Server
All Message Boards...
Application Lifecycle
>
Running a Business
Sales / Marketing
Collaboration / Beta Testing
Work Issues
Design and Architecture
Artificial Intelligence
ASP.NET
JavaScript
Internet of Things
C / C++ / MFC
>
ATL / WTL / STL
Managed C++/CLI
C#
Free Tools
Objective-C and Swift
Database
Hardware & Devices
>
System Admin
Hosting and Servers
Java
Linux Programming
Python
.NET (Core and Framework)
Android
iOS
Mobile
WPF
Visual Basic
Web Development
Site Bugs / Suggestions
Spam and Abuse Watch
features
features
Competitions
News
The Insider Newsletter
The Daily Build Newsletter
Newsletter archive
Surveys
CodeProject Stuff
community
lounge
Who's Who
Most Valuable Professionals
The Lounge
The CodeProject Blog
Where I Am: Member Photos
The Insider News
The Weird & The Wonderful
help
?
What is 'CodeProject'?
General FAQ
Ask a Question
Bugs and Suggestions
Article Help Forum
About Us
Search within:
Articles
Quick Answers
Messages
Comments by JudyL_MD (Top 11 by date)
JudyL_MD
19-May-23 22:19pm
View
as I said, the Finalize_ call does NOT return from the call into media foundation only on Win11
JudyL_MD
19-May-23 22:10pm
View
I've seen it and the "fix" was something I've already got -- correct synchronization around usages of the sink writer.
JudyL_MD
6-May-22 9:10am
View
NOT SUCCESS. You need a working version of those IF statements. Once you get data with those IF statements, then you have success.
Your driver must NOT assume that the provided buffers are the correct length. A correctly coded driver checks the length of the buffer and never writes more data than the length indicates. If you don't get anything with the IF statements, that means there is some logic error. Probably a disconnect between how long the driver thinks a ULONG is and how long VB.net thinks a ulong is. And my math may be off on the string length leaving space for the NULL - maybe a +1 instead of a -1. Don't know. That's the kind of thing I check with a debugger to make sure I got it right.
You need to put debug statements in the driver to print out the two values it is comparing in the IF statements and see what is wrong. I can't help with this anymore since I can't run your app / driver pair of program. Time to debug and see what the driver is doing with those IF statements.
I can't emphasize enough that you MUST validate the length of the buffer before you write data to it in a driver. This is driver 101 stuff. Did you read and understand the link Dave (radnor) gave you? Do so! https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/security-issues-for-i-o-control-codes
Don't get rid of those IF statements - FIX them.
JudyL_MD
5-May-22 9:46am
View
LOL ... seriously though, based on the OP's initial "working" code, I think we can safely assume he is using METHOD_BUFFERED. In that case, no MDL mapping is needed and I added the needed length validation in my comments.
JudyL_MD
4-May-22 15:24pm
View
In general, I'm advocating splitting the retrieval of the PID and the path into two separate calls. I'd advise doing some studying on the different models of memory management used in unmanaged versus managed code. Drivers themselves are a very unique subset of unmanaged code and have their own restrictions and function calls.
Now to specifics ... You asked about my comments. I've listed the big three below.
1) I'd create a new code to make it easy in the driver to tell the difference between the ulong and the string. The code is just a number ...
You were asking if you should create another IOCTL for retrieving the path. Yes you should. Somewhere in your VB, you have IO_GET_CLIENT_PROCID defined; that value gets itself turned into the switch value SEND_TO_USER in the driver. Make a second such "ioctl code" such as IO_GET_CLIENT_PROCPATH, which you must support with a new case in the driver's switch, such as SEND_TO_USER_PATH. Your VB code then calls DeviceIoControl twice, once with each of the two IO control codes. "Just a number" refers to the code value itself -- it's just a UINT with a very specific format to its bits.
2) Your ulong VB code then needs to allocate an unmanaged buffer, call the driver using the pointer to the buffer as the output parameter, then retrieve the ulong value from the pointer
The IOCTL handling function in a driver only takes one type as input and one type as output -- a pointer to a chunk of unmanaged memory. In your old code, VB.net hid those details from you. When you had "<out> ByRef OutBuffer As ULong" describing the OutBuffer parameter, VB created an unmanaged chunk of memory and got a pointer to it, copied the value of your ulong into that memory ... or more likely just locked the memory location of your ulong variable and got a pointer to the locked location ... then passed that pointer through to the DeviceIoControl function in Kernel32.DLL.
To use DeviceIoControl properly, you're going to need to do that hidden stuff yourself. (I'm speaking C# pseudo-code here):
IntPtr p = Marshall.AllocHGlobal (sizeof (ulong))
DeviceIoControl (hFile, IO_GET_CLIENT_PROCID, Nothing, 0, p, sizeof (ulong), Bytes_IO, Nothing)
check return value from DeviceIoControl
ulong value = Marshall.ReadInt64 (p);
Marshall.FreeHGlobal (p);
For the string case, you need to allocate a string of the max possible size and then use that in your call to the driver. I've got "* 2" below since you have unicode in the driver and that takes 2 bytes per character, and "+ 1" to leave room for the NULL terminator.
numStringBytes = (MAX_STRING_SIZE + 1) * 2
IntPtr p = Marshall.AllocHGlobal (numStringBytes)
DeviceIoControl (hFile, IO_GET_CLIENT_PROCPATH, Nothing, 0, p, numStringBytes, Bytes_IO, Nothing)
check return value from DeviceIoControl
string = Marshall.PtrToStringUni (p)
Marshall.FreeHGlobal (p);
3) (Now the driver code) You'll need to revise your driver code to validate the length of the buffer against the length of a ulong
sizeof (*buffer) is not the right way to either validate input length or set return length. Remember, the driver is pure C code. For the IO_GET_CLIENT_PROCID that already exists to retrieve the process ID, your switch case should be something like:
case SEND_TO_USER:
if (outLength == sizeof (ULONG))
{
*((ULONG *) buffer) = ProcID;
status = STATUS_SUCCESS;
returnLength = sizeof(ULONG);
}
for your new ioctl code
case SEND_TO_USER_PATH:
if (outLength <= (myUnicodeString.Length / 2) - 1) // leave space for the NULL terminator
{
RtlFillMemory (buffer, nOutBufferSize, 0);
RtlCopyBytes (buffer, myUnicodeString.buffer, myUnocdeString.Length * 2);
status = STATUS_SUCCESS;
returnLength = myUnocdeString.Length * 2;
}
JudyL_MD
26-Oct-21 10:22am
View
I always set my C# and C to the environment on which the app will run. If you're actually using a 32-bit machine, yes use the x86 mode. If you're running on a 64-bit machine, set your C# to 64-bit (AnyCPU for the target and _uncheck_ Prefer 32-bit) and use x64 for your C code. If needed, I deliver two versions in my installer. I don't trust 32- to 64-bit thunking so I _always_ match my C code to my machine hardware.
You're getting absolutely no indications why the C# processes are aborting? You may need to add your own logging to see where the problems are. Make sure your error checking is robust -- if it can error, even for the most obscure reasons, check those return codes! My only other thought is to check that your C routines are truly re-entrant.
Good luck.
JudyL_MD
4-Jun-20 8:44am
View
In addition to what Patrice said ... the debugger in Android Studio is pretty good. Also, look in your LogCat output; find and click the tab along the bottom of Android Studio that says LogCat. There should be entries reporting what exception was thrown that crashed your app. Look for the lines in red (the default color for the ERROR output), and it will show you the call stack. It will even allow you to click on the line and take you right to that spot in the source code that generated the exception.
JudyL_MD
8-May-20 9:58am
View
Yes, that's where the reference page you linked to does its work. Replace that WriteLine with the actions you want to execute.
JudyL_MD
17-Apr-20 11:29am
View
For English at least, unicode will show in a memory area as a recognizable ascii character followed by a byte of 0, then another character and another 0. Unicode is a 2-byte encoding and for those languages that don't need the upper byte, the 2nd byte is always a 0. It's pretty distinctive-looking in memory ... char 00 char 00 char 00
JudyL_MD
11-Feb-11 11:28am
View
Thanks
1 - see response to d@nish (functions are in caller, not the derived class)
2 - If I've got to have the "check for each possible type" I'd just rather leave it here, since this is the only place that has to do this. A factory is probably overkill for this case.
JudyL_MD
11-Feb-11 11:25am
View
Yes, I have a HandleRecord for each record type. They are NOT in the derived classes, they are in the class processing the records and need to stay there because of the processing that is done. (I have this.HandleRecord in my actual code but I missed it when typing here).
Show More