-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Cfgmgr32 functions for navigating device tree #984
Conversation
c1f8cc2
to
013fc55
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general this looks good. I have a small nitpick - see separate comment.
Memory buffer = new Memory(deviceIdLength * charToBytes); | ||
|
||
// Fetch the buffer | ||
Cfgmgr32.INSTANCE.CM_Get_Device_ID(devInst, buffer, deviceIdLength, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check the return of CM_Get_Device_ID
. The call sequence is correct, but the identifier could increase in length between the call to CM_Get_Device_ID_Size
and here. Then either a second call can be tried or an error be raised.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, the function returns success in the case where there's enough room for the characters but not the null terminator. I've tried one way of handling it (incrementing until successful). We could also keep re-measuring the length to try to include the null. Let me know which you'd prefer.
0d311d9
to
2789bda
Compare
I had another look at
Could you please have a look at the attached patch? |
I don't think your patch fixes the problem. Other than capping the number of retries, you do the same thing: get id size, add one, fetch the id. This will work 99.9999% of the time. Clearing the buffer doesn't make a difference. The edge case occurs if both:
The problem isn't adding the character -- we could allocate 4096 bytes and almost certainly ensure we have enough length (and a null terminator). But we still wouldn't be sure. The problem is that we can't trust the return code to guarantee the presence of a null. Either the string is less than the allocated length (and there's a null) or the string is exactly the allocated length (and there's no null). If you specify the exact length of the string, I think one workaround is to not use Another workaround would be to take the returned buffer, allocate a new buffer 1 character larger (and clear it or just write 0 to the last character), copy the original buffer over byte-by-byte, and then use |
OK, I gave it another shot. Fundamental differences:
|
To give some more context to my suggestion - the important part of my suggestion was this:
The last index For your current implementation: Hardcoding |
Ah, I missed the subtlety there where the length you were passing to I think my latest patch matches your suggestion except I only did one retry. Unless you think my implementation with better byte[] and char[] treatment is preferred to the buffer shenanigans (I think it actually would be more readable that way.) |
Actually, after rereading the docs, I think the "shenanigans" version I have currently committed is better, as the docs specifically mention adding room for the null. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - I agree with your change. I added two final comments, please have a look at them.
|
||
// Get Device ID character count | ||
IntByReference pulLen = new IntByReference(); | ||
Cfgmgr32.INSTANCE.CM_Get_Device_ID_Size(pulLen, devInst, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add a return value check here - if this is not CR_SUCCESS
throw an Cfgmgr32Exception
exception with the value.
* local machine. | ||
* @return The device instance ID string. | ||
*/ | ||
public static String CM_Get_Device_ID(int devInst) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add throws Cfgmgr32Exception
to the signature. It does not need to be there, but I think it is clearer, that the caller should be prepared for the exception.
Should be good to go now. Thanks for your patience with an amateur coder, your code reviews are very instructive! One of these days I'll get a PR through without modifications. :) |
Thank you for your effort. This looks good. I'll merge it. |
No description provided.