Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
264 views
in Technique[技术] by (71.8m points)

How can i write this function using SAL annotations for C in Visual Studio?

How can i write this function using SAL annotations for C? I need to implement some functions and i dont know how to declare them. I just need 1 function as a model, so i can implement the rest.

Down here is my main C file with take all the hanldes i have implemented, i dont need to modifiy this.

static void
PrintHelp()
{
    printf("Available commands:
");
    printf("> register <username> <password>
");
    printf("> login <username> <password>
");
    printf("> logout
");
    printf("> store <source file path> <submission name>
");
    printf("> retrieve <submission name> <destination file path>
");
    printf("> exit
");
}

int main()
{
    char command[10];
    char arg1[50];
    char arg2[50];

    NTSTATUS status = GlobalDataInitialize();
    if (!NT_SUCCESS(status))
    {
        printf("GlobalDataInitialize failed with NTSTATUS = 0x%X
", status);
        assert(FALSE);
        return -1;
    }

    PrintHelp();
    do
    {
        printf("Enter your command:
");
        scanf("%s", command);

        if (memcmp(command, "register", sizeof("register")) == 0)
        {
            scanf("%s", arg1);    // username
            scanf("%s", arg2);    // password

            printf("register with username [%s] password [%s]
", arg1, arg2);
            SafeStorageHandleRegister(arg1, (USHORT)strlen(arg1), arg2, (USHORT)strlen(arg2));
        }
        else if (memcmp(command, "login", sizeof("login")) == 0)
        {
            scanf("%s", arg1);    // username
            scanf("%s", arg2);    // password

            printf("login with username [%s] password [%s]
", arg1, arg2);
            SafeStorageHandleLogin(arg1, (USHORT)strlen(arg1), arg2, (USHORT)strlen(arg2));
        }
        else if (memcmp(command, "logout", sizeof("logout")) == 0)
        {
            printf("logout
");
            SafeStorageHandleLogout();
        }
        else if (memcmp(command, "store", sizeof("store")) == 0)
        {
            scanf("%s", arg1);    // source file path
            scanf("%s", arg2);    // submission name

            printf("store with source file path [%s] submission name [%s]
", arg1, arg2);
            SafeStorageHandleStore(arg2, (USHORT)strlen(arg2), arg1, (USHORT)strlen(arg1));
        }
        else if (memcmp(command, "retrieve", sizeof("retrieve")) == 0)
        {
            scanf("%s", arg1);    // submission name 
            scanf("%s", arg2);    // destination file path

            printf("retrieve with submission name [%s] destination file path [%s]
", arg1, arg2);
            SafeStorageHandleRetrieve(arg1, (USHORT)strlen(arg1), arg2, (USHORT)strlen(arg2));
        }
        else if (memcmp(command, "exit", sizeof("exit")) == 0)
        {
            printf("Bye Bye!
");
            break;
        }
        else
        {
            printf("Unknown command. Try again!
");
        }
    } while (TRUE);

    return 0;

I need help implementing this registration handle function. I can see that this registration functions has these 2 parameters Username**Password and also define the type of data. I dont know how to write proper C declarations using SAL annotations to make this work.

// Handles the "register" command
// Creates the user with Username and Password specified
//      * Creates the user's subdirectory in the %APPDIR%users directory
// Fails if the user is already registered
// This command is available only if no user is currently logged in (it must fail otherwise)
// It returns STATUS_SUCCESS if everything succeeded or a proper error status otherwise.

_Must_inspect_result_
NTSTATUS
SafeStorageHandleRegister(
    _In_reads_bytes_opt_(UsernameLength) PCHAR Username,
    _In_ USHORT UsernameLength,
    _In_reads_bytes_opt_(PasswordLength) PCHAR Password, 
    _In_ USHORT PasswordLength);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Addressing the call to SafeStorageHandleRegister():

Given your original prototype:

SafeStorageHandleRegister(
_In_reads_bytes_opt_(UsernameLength) PCHAR Username,
_In_ USHORT UsernameLength,
_In_reads_bytes_opt_(PasswordLength) PCHAR Password, 
_In_ USHORT PasswordLength);

One issue is that in your call:

SafeStorageHandleRegister(arg1, (USHORT)strlen(arg1), arg2, (USHORT)strlen(arg2));

...the number of bytes specified in arguments 3 & 4 does not include room for the null byte, resulting in an incorrect number of bytes value. strlen() does not include in its calculation, but is at the end of all C strings (which are being used here.) Use sizeof(arg1) and sizeof(arg2) instead. eg:

SafeStorageHandleRegister(arg1, (USHORT)sizeof(arg1), arg2, (USHORT)sizeof(arg2));

And, because the sizeof macro returns size_t if this is your function prototype, (i.e. one that you can modify.) I suggest changing it from using USHORT to size_t for the 2nd and 4th arguments:

SafeStorageHandleRegister(
_In_reads_bytes_opt_(UsernameLength) PCHAR Username,
_In_ size_t UsernameLength,
_In_reads_bytes_opt_(PasswordLength) PCHAR Password, 
_In_ size_t PasswordLength);

...making it more readable because there will be no casts:

SafeStorageHandleRegister(arg1, sizeof(arg1), arg2, sizeof(arg2));

_Addressing potential issues for SAL notations:

This may or may not be causing your failure, but important to note anyway...

"If the caller is not allowed to pass in a null pointer, use _In_ or _Out_ instead of _In_opt_ or _Out_opt_. This applies even to a function that checks its parameters and returns an error if it is NULL when it should not be."...

So, for example:

// Incorrect
void Func1(_Out_opt_ int *p1)
{
    *p = 1;
}

// Correct
void Func2(_Out_ int *p1)
{
    *p = 1;
}

Since you do not want your functions to have the option to pass NULL pointers it would be good to consider modifying the SAL notation from _In_reads_bytes_opt_ to _In_reads_bytes_ (removing the option)

 SafeStorageHandleRegister(
_In_reads_bytes(UsernameLength) PCHAR Username,
_In_ size_t UsernameLength,
_In_reads_bytes(PasswordLength) PCHAR Password, 
_In_ size_t PasswordLength);

Much more on SAL notations.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...