Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

761 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: unicode.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef __ECM_UNICODE_H__
  11. #define __ECM_UNICODE_H__
  12. // necessary defns -- remove?
  13. #include <rpc.h>
  14. #include <rpcdce.h>
  15. #include <wincrypt.h>
  16. #include "commctrl.h"
  17. #include "commdlg.h"
  18. #include "prsht.h"
  19. #include "shellapi.h"
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. BOOL WINAPI FIsWinNT(void);
  24. BOOL WINAPI FIsWinNT5(VOID);
  25. BOOL WINAPI MkMBStrEx(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, int cchW, char ** pszMB, int *pcbConverted);
  26. BOOL WINAPI MkMBStr(PBYTE pbBuff, DWORD cbBuff, LPCWSTR wsz, char ** pszMB);
  27. void WINAPI FreeMBStr(PBYTE pbBuff, char * szMB);
  28. LPWSTR WINAPI MkWStr(char * szMB);
  29. void WINAPI FreeWStr(LPWSTR wsz);
  30. BOOL WINAPI wstr2guid(const WCHAR *pwszIn, GUID *pgOut);
  31. BOOL WINAPI guid2wstr(const GUID *pgIn, WCHAR *pwszOut);
  32. // The following is also needed for non-x86 due to the fact that the
  33. // A/W versions of the ListView_ functions do not exist.
  34. // (these are implemented in ispu\common\unicode\commctrl.cpp)
  35. HTREEITEM WINAPI TreeView_InsertItemU(
  36. HWND hwndTV,
  37. LPTVINSERTSTRUCTW lpis
  38. );
  39. int WINAPI ListView_InsertItemU(
  40. HWND hwnd,
  41. const LPLVITEMW pitem
  42. );
  43. void WINAPI ListView_SetItemTextU(
  44. HWND hwnd,
  45. int i,
  46. int iSubItem,
  47. LPCWSTR pszText
  48. );
  49. int WINAPI ListView_InsertColumnU(
  50. HWND hwnd,
  51. int i,
  52. const LPLVCOLUMNW plvC);
  53. BOOL WINAPI ListView_GetItemU(
  54. HWND hwnd,
  55. LPLVITEMW pitem
  56. );
  57. LONG WINAPI RegOpenHKCUKeyExA(
  58. HKEY hKey, // handle of open key
  59. LPCSTR lpSubKey, // address of name of subkey to open
  60. DWORD ulOptions, // reserved
  61. REGSAM samDesired, // security access mask
  62. PHKEY phkResult // address of handle of open key
  63. );
  64. //
  65. // the following api's handle the problem with impersinating another user
  66. // and having the HKEY_CURRENT_USER opened to an incorrect user's SID.
  67. //
  68. LONG WINAPI RegCreateHKCUKeyExU (
  69. HKEY hKey,
  70. LPCWSTR lpSubKey,
  71. DWORD Reserved,
  72. LPWSTR lpClass,
  73. DWORD dwOptions,
  74. REGSAM samDesired,
  75. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  76. PHKEY phkResult,
  77. LPDWORD lpdwDisposition
  78. );
  79. LONG WINAPI RegCreateHKCUKeyExA (
  80. HKEY hKey,
  81. LPCSTR lpSubKey,
  82. DWORD Reserved,
  83. LPSTR lpClass,
  84. DWORD dwOptions,
  85. REGSAM samDesired,
  86. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  87. PHKEY phkResult,
  88. LPDWORD lpdwDisposition
  89. );
  90. LONG WINAPI RegOpenHKCUKeyExU(
  91. HKEY hKey,
  92. LPCWSTR lpSubKey,
  93. DWORD ulOptions,
  94. REGSAM samDesired,
  95. PHKEY phkResult
  96. );
  97. LONG
  98. WINAPI
  99. RegOpenHKCU(
  100. HKEY *phKeyCurrentUser
  101. );
  102. LONG
  103. WINAPI
  104. RegOpenHKCUEx(
  105. HKEY *phKeyCurrentUser,
  106. DWORD dwFlags
  107. );
  108. // Normally, HKEY_USERS\CurrentSid is opened as the HKCU. However, if
  109. // HKEY_USERS\CurrentSid doesn't exist, then, HKEY_USERS\.Default is
  110. // opened. Set the following flag to only open
  111. // HKEY_USERS\.Default if the current user is the LocalSystem SID.
  112. #define REG_HKCU_LOCAL_SYSTEM_ONLY_DEFAULT_FLAG 0x1
  113. // Normally, HKEY_USERS\CurrentSid is opened as the HKCU. However, if
  114. // HKEY_USERS\CurrentSid doesn't exist, then, HKEY_USERS\.Default is
  115. // opened. Set the following flag to always disable the opening of
  116. // HKEY_USERS\.Default. If HKEY_USERS\CurrentSid doesn't exist, RegOpenHKCUEx
  117. // returns ERROR_FILE_NOT_FOUND.
  118. #define REG_HKCU_DISABLE_DEFAULT_FLAG 0x2
  119. LONG
  120. WINAPI
  121. RegCloseHKCU(
  122. HKEY hKeyCurrentUser
  123. );
  124. BOOL
  125. WINAPI
  126. GetUserTextualSidHKCU(
  127. IN LPWSTR wszTextualSid,
  128. IN OUT LPDWORD pcchTextualSid
  129. );
  130. #ifdef _M_IX86
  131. // Reg.cpp
  132. LONG WINAPI RegCreateKeyExU (
  133. HKEY hKey,
  134. LPCWSTR lpSubKey,
  135. DWORD Reserved,
  136. LPWSTR lpClass,
  137. DWORD dwOptions,
  138. REGSAM samDesired,
  139. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  140. PHKEY phkResult,
  141. LPDWORD lpdwDisposition
  142. );
  143. LONG WINAPI RegDeleteKeyU(
  144. HKEY hKey,
  145. LPCWSTR lpSubKey
  146. );
  147. LONG WINAPI RegEnumKeyExU (
  148. HKEY hKey,
  149. DWORD dwIndex,
  150. LPWSTR lpName,
  151. LPDWORD lpcbName,
  152. LPDWORD lpReserved,
  153. LPWSTR lpClass,
  154. LPDWORD lpcbClass,
  155. PFILETIME lpftLastWriteTime
  156. );
  157. LONG WINAPI RegEnumValueU (
  158. HKEY hKey,
  159. DWORD dwIndex,
  160. LPWSTR lpValueName,
  161. LPDWORD lpcbValueName,
  162. LPDWORD lpReserved,
  163. LPDWORD lpType,
  164. LPBYTE lpData,
  165. LPDWORD lpcbData
  166. );
  167. LONG RegQueryValueExU(
  168. HKEY hKey,
  169. LPCWSTR lpValueName,
  170. LPDWORD lpReserved,
  171. LPDWORD lpType,
  172. LPBYTE lpData,
  173. LPDWORD lpcbData
  174. );
  175. LONG WINAPI RegSetValueExU (
  176. HKEY hKey,
  177. LPCWSTR lpValueName,
  178. DWORD Reserved,
  179. DWORD dwType,
  180. CONST BYTE* lpData,
  181. DWORD cbData
  182. );
  183. LONG WINAPI RegDeleteValueU (
  184. HKEY hKey,
  185. LPCWSTR lpValueName
  186. );
  187. LONG WINAPI RegQueryInfoKeyU (
  188. HKEY hKey,
  189. LPWSTR lpClass,
  190. LPDWORD lpcbClass,
  191. LPDWORD lpReserved,
  192. LPDWORD lpcSubKeys,
  193. LPDWORD lpcbMaxSubKeyLen,
  194. LPDWORD lpcbMaxClassLen,
  195. LPDWORD lpcValues,
  196. LPDWORD lpcbMaxValueNameLen,
  197. LPDWORD lpcbMaxValueLen,
  198. LPDWORD lpcbSecurityDescriptor,
  199. PFILETIME lpftLastWriteTime
  200. );
  201. LONG WINAPI RegOpenKeyExU(
  202. HKEY hKey,
  203. LPCWSTR lpSubKey,
  204. DWORD ulOptions,
  205. REGSAM samDesired,
  206. PHKEY phkResult
  207. );
  208. LONG WINAPI RegConnectRegistryU (
  209. LPWSTR lpMachineName,
  210. HKEY hKey,
  211. PHKEY phkResult
  212. );
  213. // File.cpp
  214. HANDLE WINAPI CreateFileU (
  215. LPCWSTR lpFileName,
  216. DWORD dwDesiredAccess,
  217. DWORD dwShareMode,
  218. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  219. DWORD dwCreationDisposition,
  220. DWORD dwFlagsAndAttributes,
  221. HANDLE hTemplateFile
  222. );
  223. BOOL
  224. WINAPI
  225. DeleteFileU(
  226. LPCWSTR lpFileName
  227. );
  228. BOOL
  229. WINAPI
  230. CopyFileU(
  231. LPCWSTR lpwExistingFileName,
  232. LPCWSTR lpwNewFileName,
  233. BOOL bFailIfExists
  234. );
  235. BOOL
  236. WINAPI
  237. MoveFileExU(
  238. LPCWSTR lpExistingFileName,
  239. LPCWSTR lpNewFileName,
  240. DWORD dwFlags);
  241. DWORD
  242. WINAPI
  243. GetFileAttributesU(
  244. LPCWSTR lpFileName
  245. );
  246. BOOL
  247. WINAPI
  248. SetFileAttributesU(
  249. LPCWSTR lpFileName,
  250. DWORD dwFileAttributes
  251. );
  252. DWORD
  253. WINAPI
  254. GetCurrentDirectoryU(
  255. DWORD nBufferLength,
  256. LPWSTR lpBuffer);
  257. BOOL
  258. WINAPI
  259. CreateDirectoryU(
  260. LPCWSTR lpPathName,
  261. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  262. );
  263. BOOL
  264. WINAPI
  265. RemoveDirectoryU(
  266. LPCWSTR lpPathName
  267. );
  268. UINT
  269. WINAPI
  270. GetWindowsDirectoryU(
  271. LPWSTR lpBuffer,
  272. UINT uSize
  273. );
  274. UINT
  275. WINAPI
  276. GetTempFileNameU(
  277. IN LPCWSTR lpPathName,
  278. IN LPCWSTR lpPrefixString,
  279. IN UINT uUnique,
  280. OUT LPWSTR lpTempFileName
  281. );
  282. HINSTANCE WINAPI LoadLibraryU(
  283. LPCWSTR lpLibFileName
  284. );
  285. HINSTANCE WINAPI LoadLibraryExU(
  286. LPCWSTR lpLibFileName,
  287. HANDLE hFile,
  288. DWORD dwFlags
  289. );
  290. DWORD
  291. WINAPI
  292. ExpandEnvironmentStringsU(
  293. LPCWSTR lpSrc,
  294. LPWSTR lpDst,
  295. DWORD nSize
  296. );
  297. HANDLE
  298. WINAPI
  299. FindFirstFileU(
  300. IN LPCWSTR pwszDir,
  301. OUT LPWIN32_FIND_DATAW lpFindFileData
  302. );
  303. BOOL
  304. WINAPI
  305. FindNextFileU(
  306. IN HANDLE hFindFile,
  307. OUT LPWIN32_FIND_DATAW lpFindFileData
  308. );
  309. HANDLE
  310. WINAPI
  311. FindFirstChangeNotificationU(
  312. LPCWSTR pwszPath,
  313. BOOL bWatchSubtree,
  314. DWORD dwNotifyFilter
  315. );
  316. // capi.cpp
  317. BOOL WINAPI CryptAcquireContextU(
  318. HCRYPTPROV *phProv,
  319. LPCWSTR lpContainer,
  320. LPCWSTR lpProvider,
  321. DWORD dwProvType,
  322. DWORD dwFlags
  323. );
  324. BOOL WINAPI CryptEnumProvidersU(
  325. DWORD dwIndex,
  326. DWORD *pdwReserved,
  327. DWORD dwFlags,
  328. DWORD *pdwProvType,
  329. LPWSTR pwszProvName,
  330. DWORD *pcbProvName
  331. );
  332. BOOL WINAPI CryptSignHashU(
  333. HCRYPTHASH hHash,
  334. DWORD dwKeySpec,
  335. LPCWSTR lpDescription,
  336. DWORD dwFlags,
  337. BYTE *pbSignature,
  338. DWORD *pdwSigLen
  339. );
  340. BOOL WINAPI CryptVerifySignatureU(
  341. HCRYPTHASH hHash,
  342. CONST BYTE *pbSignature,
  343. DWORD dwSigLen,
  344. HCRYPTKEY hPubKey,
  345. LPCWSTR lpDescription,
  346. DWORD dwFlags
  347. );
  348. BOOL WINAPI CryptSetProviderU(
  349. LPCWSTR lpProvName,
  350. DWORD dwProvType
  351. );
  352. // Ole.cpp
  353. RPC_STATUS RPC_ENTRY UuidToStringU(
  354. UUID * Uuid,
  355. WCHAR * * StringUuid
  356. );
  357. // nt.cpp
  358. BOOL WINAPI GetUserNameU(
  359. LPWSTR lpBuffer,
  360. LPDWORD nSize
  361. );
  362. BOOL WINAPI GetComputerNameU(
  363. LPWSTR lpBuffer,
  364. LPDWORD nSize
  365. );
  366. DWORD WINAPI GetModuleFileNameU(
  367. HMODULE hModule,
  368. LPWSTR lpFilename,
  369. DWORD nSize
  370. );
  371. HMODULE WINAPI GetModuleHandleU(
  372. LPCWSTR lpModuleName // address of module name to return handle for
  373. );
  374. // user.cpp
  375. int WINAPI LoadStringU(
  376. HINSTANCE hInstance,
  377. UINT uID,
  378. LPWSTR lpBuffer,
  379. int nBufferMax
  380. );
  381. BOOL
  382. WINAPI
  383. InsertMenuU(
  384. HMENU hMenu,
  385. UINT uPosition,
  386. UINT uFlags,
  387. UINT_PTR uIDNewItem,
  388. LPCWSTR lpNewItem
  389. );
  390. DWORD WINAPI FormatMessageU(
  391. DWORD dwFlags,
  392. LPCVOID lpSource,
  393. DWORD dwMessageId,
  394. DWORD dwLanguageId,
  395. LPWSTR lpBuffer,
  396. DWORD nSize,
  397. va_list *Arguments
  398. );
  399. int
  400. WINAPI
  401. CompareStringU(
  402. LCID Locale,
  403. DWORD dwCmpFlags,
  404. LPCWSTR lpString1,
  405. int cchCount1,
  406. LPCWSTR lpString2,
  407. int cchCount2);
  408. INT_PTR WINAPI PropertySheetU(
  409. LPPROPSHEETHEADERW lppsph);
  410. HPROPSHEETPAGE WINAPI CreatePropertySheetPageU(LPCPROPSHEETPAGEW pPage);
  411. UINT WINAPI DragQueryFileU(
  412. HDROP hDrop,
  413. UINT iFile,
  414. LPWSTR lpwszFile,
  415. UINT cch);
  416. BOOL WINAPI SetWindowTextU(
  417. HWND hWnd,
  418. LPCWSTR lpString
  419. );
  420. int WINAPI GetWindowTextU(
  421. HWND hWnd,
  422. LPWSTR lpString,
  423. int nMaxCount
  424. );
  425. int WINAPI DialogBoxParamU(
  426. HINSTANCE hInstance,
  427. LPCWSTR lpTemplateName,
  428. HWND hWndParent,
  429. DLGPROC lpDialogFunc,
  430. LPARAM dwInitParam
  431. );
  432. int WINAPI DialogBoxU(
  433. HINSTANCE hInstance,
  434. LPCWSTR lpTemplateName,
  435. HWND hWndParent,
  436. DLGPROC lpDialogFunc
  437. );
  438. UINT WINAPI GetDlgItemTextU(
  439. HWND hDlg,
  440. int nIDDlgItem,
  441. LPWSTR lpString,
  442. int nMaxCount
  443. );
  444. BOOL WINAPI SetDlgItemTextU(
  445. HWND hDlg,
  446. int nIDDlgItem,
  447. LPCWSTR lpString
  448. );
  449. int WINAPI MessageBoxU(
  450. HWND hWnd ,
  451. LPCWSTR lpText,
  452. LPCWSTR lpCaption,
  453. UINT uType
  454. );
  455. int WINAPI LCMapStringU(
  456. LCID Locale,
  457. DWORD dwMapFlags,
  458. LPCWSTR lpSrcStr,
  459. int cchSrc,
  460. LPWSTR lpDestStr,
  461. int cchDest
  462. );
  463. int WINAPI GetDateFormatU(
  464. LCID Locale,
  465. DWORD dwFlags,
  466. CONST SYSTEMTIME *lpDate,
  467. LPCWSTR lpFormat,
  468. LPWSTR lpDateStr,
  469. int cchDate
  470. );
  471. int WINAPI GetTimeFormatU(
  472. LCID Locale,
  473. DWORD dwFlags,
  474. CONST SYSTEMTIME *lpTime,
  475. LPCWSTR lpFormat,
  476. LPWSTR lpTimeStr,
  477. int cchTime
  478. );
  479. BOOL WINAPI WinHelpU(
  480. HWND hWndMain,
  481. LPCWSTR lpszHelp,
  482. UINT uCommand,
  483. DWORD dwData
  484. );
  485. LRESULT WINAPI SendMessageU(
  486. HWND hWnd,
  487. UINT Msg,
  488. WPARAM wParam,
  489. LPARAM lParam
  490. );
  491. LONG WINAPI
  492. SendDlgItemMessageU(
  493. HWND hDlg,
  494. int nIDDlgItem,
  495. UINT Msg,
  496. WPARAM wParam,
  497. LPARAM lParam
  498. );
  499. LPWSTR
  500. WINAPI
  501. GetCommandLineU(void);
  502. BOOL
  503. WINAPI
  504. IsBadStringPtrU(IN LPWSTR lpsz, UINT ucchMax);
  505. void
  506. WINAPI
  507. OutputDebugStringU(IN LPWSTR lpwsz);
  508. int
  509. WINAPI
  510. DrawTextU(
  511. HDC hDC,
  512. LPCWSTR lpString,
  513. int nCount,
  514. LPRECT lpRect,
  515. UINT uFormat
  516. );
  517. //
  518. // NOTE the following fields in LPOPENFILENAMEW are NOT supported:
  519. // nFileOffset
  520. // nFileExtension
  521. // lpTemplateName
  522. //
  523. BOOL
  524. WINAPI
  525. GetSaveFileNameU(
  526. LPOPENFILENAMEW pOpenFileName
  527. );
  528. //
  529. // NOTE the following fields in LPOPENFILENAMEW are NOT supported:
  530. // nFileOffset
  531. // nFileExtension
  532. // lpTemplateName
  533. //
  534. BOOL
  535. WINAPI
  536. GetOpenFileNameU(
  537. LPOPENFILENAMEW pOpenFileName
  538. );
  539. // event.cpp
  540. HANDLE
  541. WINAPI
  542. CreateEventU(
  543. LPSECURITY_ATTRIBUTES lpEventAttributes,
  544. BOOL bManualReset,
  545. BOOL bInitialState,
  546. LPCWSTR lpName);
  547. HANDLE
  548. WINAPI
  549. RegisterEventSourceU(
  550. LPCWSTR lpUNCServerName,
  551. LPCWSTR lpSourceName);
  552. HANDLE
  553. WINAPI
  554. OpenEventU(
  555. DWORD dwDesiredAccess,
  556. BOOL bInheritHandle,
  557. LPCWSTR lpName);
  558. HANDLE
  559. WINAPI
  560. CreateMutexU(
  561. LPSECURITY_ATTRIBUTES lpMutexAttributes,
  562. BOOL bInitialOwner,
  563. LPCWSTR lpName);
  564. HANDLE
  565. WINAPI
  566. OpenMutexU(
  567. DWORD dwDesiredAccess,
  568. BOOL bInheritHandle,
  569. LPCWSTR lpName);
  570. HFONT
  571. WINAPI
  572. CreateFontIndirectU(CONST LOGFONTW *lplf);
  573. #else
  574. #define RegQueryValueExU RegQueryValueExW
  575. #define RegCreateKeyExU RegCreateKeyExW
  576. #define RegDeleteKeyU RegDeleteKeyW
  577. #define RegEnumKeyExU RegEnumKeyExW
  578. #define RegEnumValueU RegEnumValueW
  579. #define RegSetValueExU RegSetValueExW
  580. #define RegQueryInfoKeyU RegQueryInfoKeyW
  581. #define RegDeleteValueU RegDeleteValueW
  582. #define RegOpenKeyExU RegOpenKeyExW
  583. #define RegConnectRegistryU RegConnectRegistryW
  584. #define ExpandEnvironmentStringsU ExpandEnvironmentStringsW
  585. #define CreateFileU CreateFileW
  586. #define DeleteFileU DeleteFileW
  587. #define CopyFileU CopyFileW
  588. #define MoveFileExU MoveFileExW
  589. #define GetTempFileNameU GetTempFileNameW
  590. #define GetFileAttributesU GetFileAttributesW
  591. #define SetFileAttributesU SetFileAttributesW
  592. #define GetCurrentDirectoryU GetCurrentDirectoryW
  593. #define CreateDirectoryU CreateDirectoryW
  594. #define RemoveDirectoryU RemoveDirectoryW
  595. #define GetWindowsDirectoryU GetWindowsDirectoryW
  596. #define LoadLibraryU LoadLibraryW
  597. #define LoadLibraryExU LoadLibraryExW
  598. #define FindFirstFileU FindFirstFileW
  599. #define FindNextFileU FindNextFileW
  600. #define FindFirstChangeNotificationU FindFirstChangeNotificationW
  601. #define CryptAcquireContextU CryptAcquireContextW
  602. #define CryptEnumProvidersU CryptEnumProvidersW
  603. #define CryptSignHashU CryptSignHashW
  604. #define CryptVerifySignatureU CryptVerifySignatureW
  605. #define CryptSetProviderU CryptSetProviderW
  606. #define UuidToStringU UuidToStringW
  607. #define GetUserNameU GetUserNameW
  608. #define GetComputerNameU GetComputerNameW
  609. #define GetModuleFileNameU GetModuleFileNameW
  610. #define GetModuleHandleU GetModuleHandleW
  611. #define LoadStringU LoadStringW
  612. #define InsertMenuU InsertMenuW
  613. #define FormatMessageU FormatMessageW
  614. #define CompareStringU CompareStringW
  615. #define PropertySheetU PropertySheetW
  616. #define CreatePropertySheetPageU CreatePropertySheetPageW
  617. #define DragQueryFileU DragQueryFileW
  618. #define SetWindowTextU SetWindowTextW
  619. #define GetWindowTextU GetWindowTextW
  620. #define DialogBoxParamU DialogBoxParamW
  621. #define DialogBoxU DialogBoxW
  622. #define GetDlgItemTextU GetDlgItemTextW
  623. #define SetDlgItemTextU SetDlgItemTextW
  624. #define MessageBoxU MessageBoxW
  625. #define LCMapStringU LCMapStringW
  626. #define GetDateFormatU GetDateFormatW
  627. #define GetTimeFormatU GetTimeFormatW
  628. #define WinHelpU WinHelpW
  629. #define SendMessageU SendMessageW
  630. #define SendDlgItemMessageU SendDlgItemMessageW
  631. #define IsBadStringPtrU IsBadStringPtrW
  632. #define OutputDebugStringU OutputDebugStringW
  633. #define GetCommandLineU GetCommandLineW
  634. #define DrawTextU DrawTextW
  635. #define GetSaveFileNameU GetSaveFileNameW
  636. #define GetOpenFileNameU GetOpenFileNameW
  637. #define CreateEventU CreateEventW
  638. #define RegisterEventSourceU RegisterEventSourceW
  639. #define OpenEventU OpenEventW
  640. #define CreateMutexU CreateMutexW
  641. #define OpenMutexU OpenMutexW
  642. #define CreateFontIndirectU CreateFontIndirectW
  643. #endif // _M_IX86
  644. #ifdef __cplusplus
  645. } // Balance extern "C" above
  646. #endif
  647. #endif