Microsoft Docs

I don’t know if this is an appropriate question here, but I’ve seen you all answer related questions before.

Until I read it here, I was not aware of the Edit link at the top of the docs on docs.microsoft.com. Since then I have found that invaluable. What about pages that only exist on msdn.microsoft.com though? Were those selected to go away, or have they just not been ported yet?

Specifically, the page for SecLookupAccountSid() has problems, but since it is only on msdn.microsoft.com, there is no Edit link. I found references to it on docs.microsoft.com, hoping it was just missing the “For the latest version…” link, but those references link back to msdn.microsoft.com :frowning:

or have they just not been ported yet

This. Not yet ported. It’s a process.

Peter

Thanks Peter. Are we able to help with that process? Similar to the edit features on the docs pages.

Hi @rstruempf thanks for bringing this to our attention. In general, yes, everything is moving from MSDN to docs.microsoft.com. There are still pockets where things didn’t get migrated, and it looks like you found one. This one is due to an issue with the backend build system, and I just filed an internal bug to track it. For the pages that are on docs now – we love the PRs, please keep them coming!

Ted (MSFT)

Excellent, thanks Ted!

@Ted_Hudek while I’ve got your attention, I wanted to mention a couple of things that are at best non-optimal about the documentation and annotation of SecLookupAccountSid() (and likely the similar ones). Some of these I can do as proposed changes once it is ported to docs, but if there is a way to put it on the ticket, that would keep me from having to check periodically to see if it has moved. Some of them I cannot accomplish via the docs, and others might not be accepted without explanation.

P.S. This got long. Feel free to ignore it. #TLTR

The function prototype is:
NTSTATUS SecLookupAccountSid(In_ PSID Sid, Out_ PULONG NameSize, Inout_ PUNICODE_STRING NameBuffer, Out_ PULONG DomainSize, Out_opt_ PUNICODE_STRING DomainBuffer, Out_ PSID_NAME_USE NameUse);

The basic usage of the function is:

  1. Call function with &nameSize and &domainSize, but null nameBuffer and domainBuffer. This gets the needed sizes
  2. Allocate nameBuffer and optionally domainBuffer, and call again

The problems arise from the fact that this is kind of a wonky function. It attempts to use the common Windows API pattern of: given parameters of &Size and Buffer, call once with Size = 0 and Buffer = null, which fails with STATUS_BUFFER_TOO_SMALL and sets Size to the needed size. Allocate Buffer to Size bytes, and recall with &Size and Buffer. Buffer is an optional parameter, allowing the first call. But this function has two such parameter pairs, and Size doesn’t refer to the size of the corresponding buffer, but rather the MaximumLength of the string it points to. And rather than calling it with null for the buffers, you call it with zeroed out UNICODE_STRINGs (unless you don’t want Domain, in which case you actually do pass null).

One stumble I took here was that I assumed it worked like the other similar calling patterns. But if that were true, I would pass null for the buffers in the first call, and the size returned would be the size of the full buffers for the second call, and in the second call the buffer size would be taken from the size parameters. That would make the size parameters in/out, which is what the current documentation says: “On input, this value specifies the size of the domain buffer”. But the annotations show them as Out only, and in testing, that is exactly what they are. The UNICODE_STRING’s MaximumLength, not the value of the size variables, is used to determine the buffer size.

On the second call, the NameSize and DomainSize values are not used by the function. In testing, I found that they can be null in the second call, but because of the Out annotation, static analysis complains when nullptr is passed. It would be nice to have them both as Out Opt so we don’t have to pass unused parameters, esp. for DomainSize when the domain is not being queried.

I have a utility that allocates the UNICODE_STRING buffer and the string buffer at the same time for easier memory management and utilization. So I don’t have a zeroed out UNICODE_STRING unless I just declare a dummy for making the call. To this end, I tried passing null for NameBuffer on the first call, and it worked fine; NameSize was filled with the needed string size, I allocated the string buffer, and called it a second time with null for the size and the PUNICODE_STRING I had allocated, and it works like a champ. It would be kind of silly to have all of the parameters as optional, but that would keep me from having to use a dummy UNICODE_STRING on the first call or disabling the analyzer warning.

Additionally, the documentation refers to DomainBuffer incorrectly as ReferencedDomain.

P.S. PSID vs. PISID - This function uses a PSID parameter (PVOID). The token gives the owner as PISID, which points to, oddly, an SID structure. Any idea why this oddness? Is it that PSID is intended to be opaque, and PISID was used to make it an Internal pointer to SID?

_Ron

For those who may not know, Ted is one of the team who’s responsible for conceptualizing, writing, and maintaining the drivers docs. He’s super community oriented, helpful, and open to feedback. You’ll often see his name associated with bug reports and PRs on the docs.

And I am beyond happy to hear that folks like @rstruempf are filing PRs to help make the docs better. Nothing frustrates me more than when people come here with complains about the docs (reasonable or otherwise), we get them sorted out, and then they don’t bother to file a bug (or a PR) to correct their original issue for others. Community, people! It’s all about working together.

Peter

Would be nice if there were a similar way to file DDI bug reports (or
if there is, I could not find it).

file DDI bug reports

Hmmmm… You mean, bugs in how a given DDI works? Mighty rare, that.

Peter

oh had you been using FltGetFileNameInformation, you would not have though so :wink:

@Dejan_Maksimovic said:
oh had you been using FltGetFileNameInformation, you would not have though so :wink:

Yeah, I think having the function allocate the buffer for you and you just have to know to free it is a little risky, but is a little cleaner than the normal size and buffer, call twice pattern.

How does that compare to the function not working in so many cases,
that it is prudent to make your own?

The point of the function, I believe, is to provide an easy method for acquiring the name when it’s readily available. You can then choose to use other methods (queue a work item or whatever) to acquire the name when FltGetFileNameInformation can’t acquire it. This isn’t a bug in the function. It’s how it’s designed to work.

The overall design issue is that if you’re going to regularly need to the name, you need to query it early (like in PosrCreate), store it, and then use that stored value. Don’t wait for random places and times to acquire the name and expect to call a magic function to retrieve it for you. And just cope with the fact that you won’t be able to get the name in 100% of the circumstances.

That’s the thing :slight_smile:
It fails in pre-create sometimes (giving C01C0005, meaning
STATUS_FLT_INVALID_NAME_REQUEST), it fails in post create sometimes
(same status), it fails with C000000D in pre-create… that is just
from one session I had this morning.

Then, there are like 5 cases where
FltGetDestinationFileNameInformation did not work AT ALL (e.g. on DFS
on XP), and that never got fixed! Even though it was fixed on Server
2000 SP4 URP1.
This is just from one session, again.

These are not paging reads/writes, or other cases where the API is not
designed to work. They are cases where they MUST work, or the basic
functionality is missing.

Regards, Dejan.

On 3/22/19, Peter_Viscarola_(OSR)
wrote:
> OSR https://community.osr.com/
> Peter_Viscarola_(OSR) commented on Microsoft Docs
>
> The point of the function, I believe, is to provide an easy method for
> acquiring the name when it’s readily available. You can then choose to use
> other methods (queue a work item or whatever) to acquire the name when
> FltGetFileNameInformation can’t acquire it. This isn’t a bug in the
> function. It’s how it’s designed to work.
>
> The overall design issue is that if you’re going to regularly need to the
> name, you need to query it early (like in PosrCreate), store it, and then
> use that stored value. Don’t wait for random places and times to acquire
> the name and expect to call a magic function to retrieve it for you. And
> just cope with the fact that you won’t be able to get the name in 100% of
> the circumstances.
>
> –
> Reply to this email directly or follow the link below to check it out:
> https://community.osr.com/discussion/comment/293134#Comment_293134
>
> Check it out:
> https://community.osr.com/discussion/comment/293134#Comment_293134
>

How does that compare to the function not working in so many cases,

Apparently, you are referring to STATUS_FLT_NAME_CACHE_MISS status,right…

Sorry, but this is the way it works with “fast” functions - if the “fast” path is impossible at the moment they return a failure so that you have to take a longer one

Anton Bassov

No, CACHE_MISS is a totally acceptable error, that is not even a problem.
Pre-create is pre-create IRP, not fast I/O.

@Dejan_Maksimovic said:
It fails in pre-create sometimes (giving C01C0005, meaning
STATUS_FLT_INVALID_NAME_REQUEST), it fails in post create sometimes
(same status), it fails with C000000D in pre-create… that is just
from one session I had this morning.

We use it in precreate constantly without problems. We volume and directory actions, paging file actions, and any IRPs where the file object is null, but on everything else I can’t remember when FltGetFileNameInformation has ever failed

I just tried to check into this a bit more… and the
FltGetFileNameInformation failed us in Pre-Create, with
IoGetTopLevelIrp being NULL and Irql, obviously, being 0.
It also fails if OPENED file name is requested.

I can see the filename in the debugger, and all the names I saw were
related to Windows Defender.

This is not a case where FGFNI may fail, and Unsafe variant can’t be
called obviously (file is not opened yet).