wcsstr in Windows kernel-mode


  • administrators

    Turns out there is no equivalent function to strstr/wcsstr in the DDK/WDK and therefore available in kernel mode. But being plain old C you can roll your own so that’s what I did. Well, someone else did and I adapted 😜

    #include <crtdefs.h>
    #include <stddef.h>
    
    #pragma warning(push)
    #pragma warning( disable : 4706 )
    
    //
    // Stolen from here: https://github.com/lattera/glibc/blob/master/wcsmbs/wcsstr.c
    // 
    wchar_t *kmwcsstr(const wchar_t *haystack, const wchar_t *needle)
    {
        register wchar_t b, c;
    
        if ((b = *needle) != L'\0')
        {
            haystack--;				/* possible ANSI violation */
            do
                if ((c = *++haystack) == L'\0')
                    goto ret0;
            while (c != b);
    
            if (!(c = *++needle))
                goto foundneedle;
            ++needle;
            goto jin;
    
            for (;;)
            {
                register wchar_t a;
                register const wchar_t *rhaystack, *rneedle;
    
                do
                {
                    if (!(a = *++haystack))
                        goto ret0;
                    if (a == b)
                        break;
                    if ((a = *++haystack) == L'\0')
                        goto ret0;
                shloop:;
                } while (a != b);
    
            jin:	  if (!(a = *++haystack))
                goto ret0;
    
                      if (a != c)
                          goto shloop;
    
                      if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))
                          do
                          {
                              if (a == L'\0')
                                  goto foundneedle;
                              if (*++rhaystack != (a = *++needle))
                                  break;
                              if (a == L'\0')
                                  goto foundneedle;
                          } while (*++rhaystack == (a = *++needle));
    
                          needle = rneedle;		  /* took the register-poor approach */
    
                          if (a == L'\0')
                              break;
            }
        }
    foundneedle:
        return (wchar_t*)haystack;
    ret0:
        return NULL;
    }
    #pragma warning(pop)
    

    Word of warning: only use with PCWSTR! It expects the passed strings to be NULL-terminated, so don’t use with UNICODE_STRING!

    Cheers!