Skip to content

Commit c4b16c6

Browse files
committed
FindNLSString function, winnls.h line 1637
1 parent 9c06b91 commit c4b16c6

File tree

3 files changed

+267
-14
lines changed

3 files changed

+267
-14
lines changed

src-native/THNETII.WinApi.Headers.WinNls/CSTR_FLAGS.cs renamed to src-native/THNETII.WinApi.Headers.WinNls/NLSSTRING_FLAGS.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
namespace THNETII.WinApi.Native.WinNls
44
{
55
[Flags]
6-
public enum CSTR_FLAGS : int
6+
public enum NLSSTRING_FLAGS : int
77
{
8+
//
9+
// String Flags.
10+
//
811
/// <summary>
912
/// Ignore case. For many scripts (notably Latin scripts), <see cref="NORM_IGNORECASE"/> coincides with <see cref="LINGUISTIC_IGNORECASE"/>.
1013
/// <para><note><see cref="NORM_IGNORECASE"/> ignores any tertiary distinction, whether it is actually linguistic case or not. For example, in Arabic and Indic scripts, this distinguishes alternate forms of a character, but the differences do not correspond to linguistic case. <see cref="LINGUISTIC_IGNORECASE"/> causes the function to ignore only actual linguistic casing, instead of ignoring the third sorting weight.</note></para>
@@ -37,6 +40,48 @@ public enum CSTR_FLAGS : int
3740
/// <summary>Use the default linguistic rules for casing, instead of file system rules. Note that most scenarios for <see cref="CompareStringEx"/> use this flag. This flag does not have to be used when your application calls <see cref="CompareStringOrdinal"/>.</summary>
3841
NORM_LINGUISTIC_CASING = WinNlsConstants.NORM_LINGUISTIC_CASING,
3942

43+
//
44+
// Search Flags
45+
//
46+
/// <summary>Test to find out if the value to find is the first value in the source string.</summary>
47+
FIND_STARTSWITH = WinNlsConstants.FIND_STARTSWITH,
48+
/// <summary>Test to find out if the value to find is the last value in the source string.</summary>
49+
FIND_ENDSWITH = WinNlsConstants.FIND_ENDSWITH,
50+
/// <summary>Search the string, starting with the first character of the string.</summary>
51+
FIND_FROMSTART = WinNlsConstants.FIND_FROMSTART,
52+
/// <summary>Search the string in the reverse direction, starting with the last character of the string.</summary>
53+
FIND_FROMEND = WinNlsConstants.FIND_FROMEND,
54+
55+
//
56+
// Sorting Flags.
57+
//
58+
// WORD Sort: culturally correct sort
59+
// hyphen and apostrophe are special cased
60+
// example: "coop" and "co-op" will sort together in a list
61+
//
62+
// co_op <------- underscore (symbol)
63+
// coat
64+
// comb
65+
// coop
66+
// co-op <------- hyphen (punctuation)
67+
// cork
68+
// went
69+
// were
70+
// we're <------- apostrophe (punctuation)
71+
//
72+
//
73+
// STRING Sort: hyphen and apostrophe will sort with all other symbols
74+
//
75+
// co-op <------- hyphen (punctuation)
76+
// co_op <------- underscore (symbol)
77+
// coat
78+
// comb
79+
// coop
80+
// cork
81+
// we're <------- apostrophe (punctuation)
82+
// went
83+
// were
84+
//
4085
/// <summary>Treat punctuation the same as symbols.</summary>
4186
SORT_STRINGSORT = WinNlsConstants.SORT_STRINGSORT,
4287
/// <summary><strong>Windows 7</strong>: Treat digits as numbers during sorting, for example, sort <c>"2"</c> before <c>"10"</c>.</summary>

src-native/THNETII.WinApi.Headers.WinNls/WinNlsFunctions.cs

Lines changed: 148 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ out CPINFOEX lpCPInfoEx
329329
[Obsolete("DEPRECATED: StringApiSetFunction.CompareStringEx is preferred")]
330330
public static CSTR_RESULT CompareStringA(
331331
int Locale,
332-
CSTR_FLAGS dwCmpFlags,
332+
NLSSTRING_FLAGS dwCmpFlags,
333333
string lpString1,
334334
string lpString2
335335
) =>
@@ -351,7 +351,7 @@ string lpString2
351351
private static extern CSTR_RESULT CompareStringA(
352352
[In] int Locale,
353353
[In, MarshalAs(UnmanagedType.I4)]
354-
CSTR_FLAGS dwCmpFlags,
354+
NLSSTRING_FLAGS dwCmpFlags,
355355
[In] string lpString1,
356356
[In] int cchCount1,
357357
[In] string lpString2,
@@ -362,7 +362,7 @@ [In] int cchCount2
362362
[Obsolete("DEPRECATED: StringApiSetFunction.CompareStringEx is preferred")]
363363
public unsafe static CSTR_RESULT CompareStringA(
364364
int Locale,
365-
CSTR_FLAGS dwCmpFlags,
365+
NLSSTRING_FLAGS dwCmpFlags,
366366
ReadOnlySpan<byte> lpString1,
367367
int cchCount1,
368368
ReadOnlySpan<byte> lpString2,
@@ -391,7 +391,7 @@ int cchCount2
391391
public static extern CSTR_RESULT CompareStringA(
392392
[In] int Locale,
393393
[In, MarshalAs(UnmanagedType.I4)]
394-
CSTR_FLAGS dwCmpFlags,
394+
NLSSTRING_FLAGS dwCmpFlags,
395395
[In] LPCSTR lpString1,
396396
[In] int cchCount1,
397397
[In] LPCSTR lpString2,
@@ -403,7 +403,7 @@ [In] int cchCount2
403403
/// <inheritdoc cref="CompareString"/>
404404
public static CSTR_RESULT CompareStringW(
405405
int Locale,
406-
CSTR_FLAGS dwCmpFlags,
406+
NLSSTRING_FLAGS dwCmpFlags,
407407
string lpString1,
408408
string lpString2
409409
) =>
@@ -421,7 +421,7 @@ string lpString2
421421
private static extern CSTR_RESULT CompareStringW(
422422
[In] int Locale,
423423
[In, MarshalAs(UnmanagedType.I4)]
424-
CSTR_FLAGS dwCmpFlags,
424+
NLSSTRING_FLAGS dwCmpFlags,
425425
[In] string lpString1,
426426
[In] int cchCount1,
427427
[In] string lpString2,
@@ -431,7 +431,7 @@ [In] int cchCount2
431431
/// <inheritdoc cref="CompareString"/>
432432
public unsafe static CSTR_RESULT CompareStringW(
433433
int Locale,
434-
CSTR_FLAGS dwCmpFlags,
434+
NLSSTRING_FLAGS dwCmpFlags,
435435
ReadOnlySpan<char> lpString1,
436436
ReadOnlySpan<char> lpString2
437437
)
@@ -454,7 +454,7 @@ ReadOnlySpan<char> lpString2
454454
public static extern CSTR_RESULT CompareStringW(
455455
[In] int Locale,
456456
[In, MarshalAs(UnmanagedType.I4)]
457-
CSTR_FLAGS dwCmpFlags,
457+
NLSSTRING_FLAGS dwCmpFlags,
458458
[In] LPCWSTR lpString1,
459459
[In] int cchCount1,
460460
[In] LPCWSTR lpString2,
@@ -492,7 +492,7 @@ [In] int cchCount2
492492
/// <remarks>
493493
/// <para>See Remarks for <see cref="CompareStringEx"/>.</para>
494494
/// <para>If your application is calling the ANSI version of <see cref="CompareString"/>, the function converts parameters via the default code page of the supplied locale. Thus, an application can never use <see cref="CompareString"/> to handle UTF-8 text.</para>
495-
/// <para>Normally, for case-insensitive comparisons, <see cref="CompareString"/> maps the lowercase <c>"i"</c> to the uppercase <c>"I"</c>, even when the locale is Turkish or Azerbaijani. The <see cref="CSTR_FLAGS.NORM_LINGUISTIC_CASING"/> flag overrides this behavior for Turkish or Azerbaijani. If this flag is specified in conjunction with Turkish or Azerbaijani, <c>LATIN SMALL LETTER DOTLESS I (U+0131)</c> is the lowercase form of <c>LATIN CAPITAL LETTER I (U+0049)</c> and <c>LATIN SMALL LETTER I (U+0069)</c> is the lowercase form of <c>LATIN CAPITAL LETTER I WITH DOT ABOVE (U+0130)</c>.</para>
495+
/// <para>Normally, for case-insensitive comparisons, <see cref="CompareString"/> maps the lowercase <c>"i"</c> to the uppercase <c>"I"</c>, even when the locale is Turkish or Azerbaijani. The <see cref="NLSSTRING_FLAGS.NORM_LINGUISTIC_CASING"/> flag overrides this behavior for Turkish or Azerbaijani. If this flag is specified in conjunction with Turkish or Azerbaijani, <c>LATIN SMALL LETTER DOTLESS I (U+0131)</c> is the lowercase form of <c>LATIN CAPITAL LETTER I (U+0049)</c> and <c>LATIN SMALL LETTER I (U+0069)</c> is the lowercase form of <c>LATIN CAPITAL LETTER I WITH DOT ABOVE (U+0130)</c>.</para>
496496
/// <para>
497497
/// <list type="table">
498498
/// <listheader><term>Requirements</term></listheader>
@@ -504,10 +504,16 @@ [In] int cchCount2
504504
/// </remarks>
505505
/// <exception cref="DllNotFoundException">The native library containg the function could not be found.</exception>
506506
/// <exception cref="EntryPointNotFoundException">Unable to find the entry point for the function in the native library.</exception>
507+
/// <seealso cref="CompareStringEx"/>
508+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/handling-sorting-in-your-applications">Handling Sorting in Your Applications</seealso>
509+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/national-language-support">National Language Support</seealso>
510+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/national-language-support-functions">National Language Support Functions</seealso>
511+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/security-considerations--international-features">Security Considerations: International Features</seealso>
512+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/using-unicode-normalization-to-represent-strings">Using Unicode Normalization to Represent Strings</seealso>
507513
[Obsolete("DEPRECATED: StringApiSetFunction.CompareStringEx is preferred")]
508514
public static CSTR_RESULT CompareString(
509515
int Locale,
510-
CSTR_FLAGS dwCmpFlags,
516+
NLSSTRING_FLAGS dwCmpFlags,
511517
string lpString1,
512518
string lpString2
513519
) =>
@@ -534,7 +540,7 @@ private static
534540
CSTR_RESULT CompareString(
535541
[In] int Locale,
536542
[In, MarshalAs(UnmanagedType.I4)]
537-
CSTR_FLAGS dwCmpFlags,
543+
NLSSTRING_FLAGS dwCmpFlags,
538544
[In] string lpString1,
539545
[In] int cchCount1,
540546
[In] string lpString2,
@@ -557,7 +563,7 @@ [In] int cchCount2
557563
[Obsolete("DEPRECATED: StringApiSetFunction.CompareStringEx is preferred")]
558564
public unsafe static CSTR_RESULT CompareString(
559565
int Locale,
560-
CSTR_FLAGS dwCmpFlags,
566+
NLSSTRING_FLAGS dwCmpFlags,
561567
ReadOnlySpan<byte> lpString1,
562568
int cchCount1,
563569
ReadOnlySpan<byte> lpString2,
@@ -591,7 +597,7 @@ public static
591597
CSTR_RESULT CompareString(
592598
[In] int Locale,
593599
[In, MarshalAs(UnmanagedType.I4)]
594-
CSTR_FLAGS dwCmpFlags,
600+
NLSSTRING_FLAGS dwCmpFlags,
595601
[In] LPCTSTR lpString1,
596602
[In] int cchCount1,
597603
[In] LPCTSTR lpString2,
@@ -614,7 +620,136 @@ [In] int cchCount2
614620
#endregion
615621
// C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\WinNls.h, line 1626
616622
#region FindNLSString function
623+
/// <summary>
624+
/// Locates a Unicode string (wide characters) or its equivalent in another Unicode string for a locale specified by identifier.
625+
/// <para><note type="caution">Because strings with very different binary representations can compare as identical, this function can raise certain security concerns. For more information, see the discussion of comparison functions in <a href="https://docs.microsoft.com/windows/desktop/Intl/security-considerations--international-features">Security Considerations: International Features</a>.</note></para>
626+
/// <para><note>For interoperability reasons, the application should prefer the <see cref="FindNLSStringEx"/> function because Microsoft is migrating toward the use of locale names instead of locale identifiers for new locales. Although <see cref="FindNLSString"/> supports custom locales, most applications should use <see cref="FindNLSStringEx"/> for this type of support.</note></para>
627+
/// </summary>
628+
/// <param name="Locale">
629+
/// <a href="https://docs.microsoft.com/windows/desktop/Intl/locale-identifiers">Locale identifier</a> that specifies the locale. You can use the <see cref="MAKELCID"/> macro to create an identifier or use one of the following predefined values.
630+
/// <list type="bullet">
631+
/// <item><see cref="LOCALE_INVARIANT"/></item>
632+
/// <item><see cref="LOCALE_SYSTEM_DEFAULT"/></item>
633+
/// <item><see cref="LOCALE_USER_DEFAULT"/></item>
634+
/// </list>
635+
/// <strong>Windows Vista and later</strong>: The following custom locale identifiers are also supported.
636+
/// <list type="bullet">
637+
/// <item><see cref="LOCALE_CUSTOM_DEFAULT"/></item>
638+
/// <item><see cref="LOCALE_CUSTOM_UI_DEFAULT"/></item>
639+
/// <item><see cref="LOCALE_CUSTOM_UNSPECIFIED"/></item>
640+
/// </list>
641+
/// </param>
642+
/// <param name="dwFindNLSStringFlags">Flags specifying details of the find operation. For detailed definitions, see the <em>dwFindNLSStringFlags</em> parameter of <see cref="FindNLSStringEx"/>.</param>
643+
/// <param name="lpStringSource">
644+
/// The source string, in which the function searches for the string specified by <paramref name="lpStringValue"/>.
645+
/// <para>The application cannot specify <c>0</c> (zero) or any negative number other than <c>-1</c> for the parameter specifying the length of the string (if any). The application specifies <c>-1</c> for the length if the source string is null-terminated and the function should calculate the size automatically.</para>
646+
/// </param>
647+
/// <param name="lpStringValue">
648+
/// The search string, for which the function searches in the source string.
649+
/// <para>The application cannot specify <c>0</c> (zero) or any negative number other than <c>-1</c> for the parameter specifying the length of the string (if any). The application specifies <c>-1</c> for the length if the source string is null-terminated and the function should calculate the size automatically.</para>
650+
/// </param>
651+
/// <param name="pcchFound">Receives the length of the string that the function finds. For details, see the <em>pcchFound</em> parameter of <see cref="FindNLSStringEx"/>.</param>
652+
/// <returns>
653+
/// <para>Returns a 0-based index into the source string indicated by <paramref name="lpStringSource"/> if successful. In combination with the value in <paramref name="pcchFound"/>, this index provides the exact location of the entire found string in the source string. A return value of <c>0</c> (zero) is an error-free index into the source string, and the matching string is in the source string at offset <c>0</c>.</para>
654+
/// <para>
655+
/// The function returns <c>-1</c> if it does not succeed. To get extended error information, the application can call <see cref="Marshal.GetLastWin32Error"/>, which can return one of the following error codes:
656+
/// <list type="table">
657+
/// <listheader><term>Error code</term><description>Reason</description></listheader>
658+
/// <item><term><see cref="ERROR_INVALID_FLAGS"/></term><description>The values supplied for flags were not valid.</description></item>
659+
/// <item><term><see cref="ERROR_INVALID_PARAMETER"/></term><description>Any of the parameter values was invalid.</description></item>
660+
/// <item><term><see cref="ERROR_SUCCESS"/></term><description>The action completed successfully but yielded no results.</description></item>
661+
/// </list>
662+
/// </para>
663+
/// </returns>
664+
/// <remarks>
665+
/// See Remarks for <see cref="FindNLSStringEx"/>.
666+
/// <para>
667+
/// <list type="table">
668+
/// <listheader><term>Requirements</term></listheader>
669+
/// <item><term><strong>Minimum supported client:</strong></term><description>Windows Vista [desktop apps only]</description></item>
670+
/// <item><term><strong>Minimum supported server:</strong></term><description>Windows Server 2008 [desktop apps only]</description></item>
671+
/// </list>
672+
/// </para>
673+
/// <para>Microsoft Docs page: <a href="https://docs.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-findnlsstring">FindNLSString function</a></para>
674+
/// </remarks>
675+
/// <exception cref="DllNotFoundException">The native library containg the function could not be found.</exception>
676+
/// <exception cref="EntryPointNotFoundException">Unable to find the entry point for the function in the native library.</exception>
677+
/// <seealso cref="CompareString"/>
678+
/// <seealso cref="FindNLSStringEx"/>
679+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/handling-sorting-in-your-applications">Handling Sorting in Your Applications</seealso>
680+
/// <seealso cref="LCMapString"/>
681+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/national-language-support">National Language Support</seealso>
682+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/national-language-support-functions">National Language Support Functions</seealso>
683+
/// <seealso href="https://docs.microsoft.com/windows/desktop/Intl/security-considerations--international-features">Security Considerations: International Features</seealso>
684+
[Obsolete("DEPRECATED: FindNLSStringEx is preferred")]
685+
public static int FindNLSString(
686+
int Locale,
687+
NLSSTRING_FLAGS dwFindNLSStringFlags,
688+
string lpStringSource,
689+
string lpStringValue,
690+
out int pcchFound
691+
) =>
692+
FindNLSString(
693+
Locale,
694+
dwFindNLSStringFlags,
695+
lpStringSource,
696+
lpStringSource?.Length ?? 0,
697+
lpStringValue,
698+
lpStringValue?.Length ?? 0,
699+
out pcchFound
700+
);
701+
702+
[Obsolete("DEPRECATED: FindNLSStringEx is preferred")]
703+
[DllImport(Kernel32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
704+
private static extern int FindNLSString(
705+
[In] int Locale,
706+
[In, MarshalAs(UnmanagedType.I4)]
707+
NLSSTRING_FLAGS dwFindNLSStringFlags,
708+
[In, MarshalAs(UnmanagedType.LPWStr)]
709+
string lpStringSource,
710+
[In] int cchSource,
711+
[In, MarshalAs(UnmanagedType.LPWStr)]
712+
string lpStringValue,
713+
[In] int cchValue,
714+
out int pcchFound
715+
);
716+
717+
/// <inheritdoc cref="FindNLSString"/>
718+
[Obsolete("DEPRECATED: FindNLSStringEx is preferred")]
719+
public static unsafe int FindNLSString(
720+
int Locale,
721+
NLSSTRING_FLAGS dwFindNLSStringFlags,
722+
ReadOnlySpan<char> lpStringSource,
723+
ReadOnlySpan<char> lpStringValue,
724+
out int pcchFound
725+
)
726+
{
727+
fixed (char* ptrStringSource = lpStringSource)
728+
fixed (char* ptrStringValue = lpStringValue)
729+
return FindNLSString(
730+
Locale,
731+
dwFindNLSStringFlags,
732+
Pointer.Create<LPCWSTR>(ptrStringSource),
733+
lpStringSource.Length,
734+
Pointer.Create<LPCWSTR>(ptrStringValue),
735+
lpStringValue.Length,
736+
out pcchFound
737+
);
738+
}
617739

740+
/// <inheritdoc cref="FindNLSString"/>
741+
[Obsolete("DEPRECATED: FindNLSStringEx is preferred")]
742+
[DllImport(Kernel32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
743+
public static extern int FindNLSString(
744+
[In] int Locale,
745+
[In, MarshalAs(UnmanagedType.I4)]
746+
NLSSTRING_FLAGS dwFindNLSStringFlags,
747+
[In] LPCWSTR lpStringSource,
748+
[In] int cchSource,
749+
[In] LPCWSTR lpStringValue,
750+
[In] int cchValue,
751+
out int pcchFound
752+
);
618753
#endregion
619754
}
620755
}

0 commit comments

Comments
 (0)