everything_sdk/
raw.rs

1//! Raw function wrapper in Rust type for pure C-bindings with Windows related types
2//!
3//! This code is written based on the official SDK web documents in October 2023.
4//! The [Everything SDK Documents](https://www.voidtools.com/support/everything/sdk/)
5//! web content may be changed and updated in the future, therefore, the code logic
6//! is based on the comment documents (rustdoc) in this code instead of the web documents.
7//!
8//! Rust does a good job of supporting Unicode, so it seems that no need to support
9//! the ANSI version functions such as `Everything_SetSearchA` or `Everything_QueryA`.
10//! Therefore, this crate uses Unicode version functions ending in `W` by default.
11//! (Ref: <https://stackoverflow.com/questions/33714546/winapi-unicode-and-ansi-functions>)
12//!
13//! For input value of type `LPCWSTR` when we calling `Everything_SetSearchW` or else, we
14//! do not need to keep the memory of search text available after the return of this
15//! function, because the C code in Everything-SDK will allocate the memory to store the
16//! search text. After calling these functions, we can deallocate the memory which the
17//! input pointer points to.
18
19#![allow(non_snake_case)]
20
21use std::{
22    ffi::{OsStr, OsString},
23    fmt::Display,
24    num::NonZeroU32,
25};
26
27use bitflags::bitflags;
28use enum_primitive_derive::Primitive;
29use sdk_sys::{LARGE_INTEGER, UINT};
30use widestring::{U16CStr, U16CString};
31
32use everything_sdk_sys as sdk_sys;
33// use winapi::um::winnt::ULARGE_INTEGER;
34use windows::{
35    core::{PCWSTR, PWSTR},
36    Win32::{
37        Foundation::{BOOL, FALSE, FILETIME, HWND, LPARAM, TRUE, WPARAM},
38        Storage::FileSystem::INVALID_FILE_ATTRIBUTES,
39    },
40};
41
42// pub type LARGE_INTEGER = i64;
43// pub type ULARGE_INTEGER = u64;
44// pub type UINT = u32;
45
46// use windows::Win32::Foundation::{TRUE, FALSE, HWND};
47
48/// convert the Win32 [`BOOL`] to normal `bool`
49fn lower_bool(b: BOOL) -> bool {
50    match b {
51        TRUE => true,
52        FALSE => false,
53        _ => unreachable!(),
54    }
55}
56
57/// convert the Win32 [`BOOL`] to normal `bool`. Check LastError when FALSE.
58fn lower_bool_or_ipc_error(b: BOOL) -> Option<bool> {
59    match b {
60        TRUE => Some(true),
61        FALSE => match Everything_GetLastError() {
62            LastError::EVERYTHING_OK => Some(false),
63            LastError::EVERYTHING_ERROR_IPC => None,
64            _ => unreachable!(),
65        },
66        _ => unreachable!(),
67    }
68}
69
70/// Check if IPC Error occurred when u32 number is 0.
71fn zero_or_ipc_error(n: u32) -> Option<u32> {
72    if n == 0 {
73        match Everything_GetLastError() {
74            LastError::EVERYTHING_OK => Some(0),
75            LastError::EVERYTHING_ERROR_IPC => None,
76            _ => unreachable!(),
77        }
78    } else {
79        Some(n)
80    }
81}
82
83// --- write search state ---
84
85/// The `Everything_SetSearch` function sets the search string for the IPC Query.
86///
87/// # Arguments
88/// * `text` - An os string to be used as the new search text.
89///
90/// # Remarks
91/// - Optionally call this function prior to a call to `Everything_Query`
92/// - `Everything_Query` executes the IPC Query using this search string.
93/// - If you want to do one less memory copy (from OsStr to "valid" UTF-16 u16 array), you
94///   should use [`everything_sdk_sys::Everything_SetSearchW`] directly.
95pub fn Everything_SetSearch(text: impl AsRef<OsStr>) {
96    // string slice to `\0` end C string
97    let search_text = U16CString::from_os_str(text).expect("the nul value only in the end");
98    unsafe { sdk_sys::Everything_SetSearchW(PCWSTR(search_text.as_ptr())) };
99}
100
101/// The `Everything_SetMatchPath` function enables or disables full path matching for
102/// the next call to `Everything_Query`.
103///
104/// # Arguments
105/// * `enabled` - If `true`, full path matching is enabled, `false` is disabled.
106///
107/// # Remarks
108/// - If match full path is being enabled, the next call to `Everything_Query` will search
109///   the full path and file name of each file and folder.
110/// - If match full path is being disabled, the next call to `Everything_Query` will search
111///   the file name only of each file and folder.
112/// - Match path is disabled by default.
113/// - Enabling match path will add a significant performance hit.
114pub fn Everything_SetMatchPath(enabled: bool) {
115    let enabled: BOOL = if enabled { TRUE } else { FALSE };
116    unsafe { sdk_sys::Everything_SetMatchPath(enabled) }
117}
118
119/// The `Everything_SetMatchCase` function enables or disables full path matching for
120/// the next call to `Everything_Query`.
121///
122/// # Arguments
123/// * `sensitive` - If `true`, the search is case sensitive, `false` is case insensitive.
124///
125/// # Remarks
126/// - Match case is disabled by default.
127pub fn Everything_SetMatchCase(sensitive: bool) {
128    let enabled: BOOL = if sensitive { TRUE } else { FALSE };
129    unsafe { sdk_sys::Everything_SetMatchCase(enabled) }
130}
131
132/// The `Everything_SetMatchWholeWord` function enables or disables matching whole words
133/// for the next call to `Everything_Query`.
134///
135/// # Arguments
136/// * `enabled` - If `true`, the search matches whole words only, `false` is the search
137///   can occur anywhere.
138///
139/// # Remarks
140/// - Match whole word is disabled by default.
141pub fn Everything_SetMatchWholeWord(enabled: bool) {
142    let enabled: BOOL = if enabled { TRUE } else { FALSE };
143    unsafe { sdk_sys::Everything_SetMatchWholeWord(enabled) }
144}
145
146/// The `Everything_SetRegex` function enables or disables Regular Expression searching.
147///
148/// # Arguments
149/// * `enabled` - Set to `true` to enable regex, set to `false` to disable regex.
150///
151/// # Remarks
152/// - Regex is disabled by default.
153pub fn Everything_SetRegex(enabled: bool) {
154    let enabled: BOOL = if enabled { TRUE } else { FALSE };
155    unsafe { sdk_sys::Everything_SetRegex(enabled) }
156}
157
158/// The `Everything_SetMax` function set the maximum number of results to return
159/// from `Everything_Query`.
160///
161/// # Arguments
162/// * `max_results` - Specifies the maximum number of results to return.
163///   Setting this to `u32::MAX` (0xffffffff) will return all results.
164///
165/// # Remarks
166/// - The default maximum number of results is 0xffffffff (all results).
167/// - If you are displaying the results in a window, set the maximum number of results
168///   to the number of visible items in the window.
169pub fn Everything_SetMax(max_results: u32) {
170    unsafe { sdk_sys::Everything_SetMax(max_results) }
171}
172
173/// The `Everything_SetOffset` function set the first result offset to return from
174/// a call to `Everything_Query`.
175///
176/// # Arguments
177/// * `offset` - Specifies the first result from the available results. Set this to 0 to
178///   return the first available result.
179///
180/// # Remarks
181/// - The default offset is 0 (the first available result).
182/// - If you are displaying the results in a window with a custom scroll bar, set the
183///   offset to the vertical scroll bar position.
184/// - Using a search window can reduce the amount of data sent over the IPC and significantly
185///   increase search performance.
186pub fn Everything_SetOffset(offset: u32) {
187    unsafe { sdk_sys::Everything_SetOffset(offset) }
188}
189
190/// The `Everything_SetReplyWindow` function sets the window that will receive the the IPC
191/// Query results.
192///
193/// # Arguments
194/// * `h_wnd` - The handle to the window that will receive the IPC Query reply.
195///
196/// # Remarks
197/// - This function MUST be called before calling `Everything_Query` with `wait` set to `false`.
198/// - Check for results with the specified window using `Everything_IsQueryReply`.
199/// - Call `Everything_SetReplyID` with a unique identifier to specify multiple searches.
200///
201/// TODO: These functions coupled with the IPC mechanism that is `WM_COPYDATA` in Win32 API.
202/// ...
203#[cfg_attr(not(feature = "raw"), allow(dead_code))]
204pub fn Everything_SetReplyWindow(h_wnd: HWND) {
205    unsafe { sdk_sys::Everything_SetReplyWindow(h_wnd) }
206}
207
208/// The `Everything_SetReplyID` function sets the unique number to identify the next query.
209///
210/// # Arguments
211/// * `n_id` - The unique number to identify the next query.
212///
213/// # Remarks
214/// - The default identifier is 0.
215/// - Set a unique identifier for the IPC Query.
216/// - If you want to post multiple search queries with the same window handle, you MUST call
217///   the `Everything_SetReplyID` function to assign each query a unique identifier.
218/// - The nID value `n_id` is the `dwData` member in the `COPYDATASTRUCT` used in
219///   the `WM_COPYDATA` reply message.
220/// - This function is not required if you call `Everything_Query` with `wait` set to `true`.
221///
222/// # References
223/// - [Using Data Copy](https://learn.microsoft.com/en-us/windows/win32/dataxchg/using-data-copy)
224///
225/// TODO: These functions coupled with the IPC mechanism that is `WM_COPYDATA` in Win32 API.
226/// ...
227#[cfg_attr(not(feature = "raw"), allow(dead_code))]
228pub fn Everything_SetReplyID(n_id: u32) {
229    unsafe { sdk_sys::Everything_SetReplyID(n_id) }
230}
231
232#[repr(u32)]
233#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Primitive)]
234#[allow(non_camel_case_types)]
235pub enum SortType {
236    EVERYTHING_SORT_NAME_ASCENDING = sdk_sys::EVERYTHING_SORT_NAME_ASCENDING,
237    EVERYTHING_SORT_NAME_DESCENDING = sdk_sys::EVERYTHING_SORT_NAME_DESCENDING,
238    EVERYTHING_SORT_PATH_ASCENDING = sdk_sys::EVERYTHING_SORT_PATH_ASCENDING,
239    EVERYTHING_SORT_PATH_DESCENDING = sdk_sys::EVERYTHING_SORT_PATH_DESCENDING,
240    EVERYTHING_SORT_SIZE_ASCENDING = sdk_sys::EVERYTHING_SORT_SIZE_ASCENDING,
241    EVERYTHING_SORT_SIZE_DESCENDING = sdk_sys::EVERYTHING_SORT_SIZE_DESCENDING,
242    EVERYTHING_SORT_EXTENSION_ASCENDING = sdk_sys::EVERYTHING_SORT_EXTENSION_ASCENDING,
243    EVERYTHING_SORT_EXTENSION_DESCENDING = sdk_sys::EVERYTHING_SORT_EXTENSION_DESCENDING,
244    EVERYTHING_SORT_TYPE_NAME_ASCENDING = sdk_sys::EVERYTHING_SORT_TYPE_NAME_ASCENDING,
245    EVERYTHING_SORT_TYPE_NAME_DESCENDING = sdk_sys::EVERYTHING_SORT_TYPE_NAME_DESCENDING,
246    EVERYTHING_SORT_DATE_CREATED_ASCENDING = sdk_sys::EVERYTHING_SORT_DATE_CREATED_ASCENDING,
247    EVERYTHING_SORT_DATE_CREATED_DESCENDING = sdk_sys::EVERYTHING_SORT_DATE_CREATED_DESCENDING,
248    EVERYTHING_SORT_DATE_MODIFIED_ASCENDING = sdk_sys::EVERYTHING_SORT_DATE_MODIFIED_ASCENDING,
249    EVERYTHING_SORT_DATE_MODIFIED_DESCENDING = sdk_sys::EVERYTHING_SORT_DATE_MODIFIED_DESCENDING,
250    EVERYTHING_SORT_ATTRIBUTES_ASCENDING = sdk_sys::EVERYTHING_SORT_ATTRIBUTES_ASCENDING,
251    EVERYTHING_SORT_ATTRIBUTES_DESCENDING = sdk_sys::EVERYTHING_SORT_ATTRIBUTES_DESCENDING,
252    EVERYTHING_SORT_FILE_LIST_FILENAME_ASCENDING =
253        sdk_sys::EVERYTHING_SORT_FILE_LIST_FILENAME_ASCENDING,
254    EVERYTHING_SORT_FILE_LIST_FILENAME_DESCENDING =
255        sdk_sys::EVERYTHING_SORT_FILE_LIST_FILENAME_DESCENDING,
256    EVERYTHING_SORT_RUN_COUNT_ASCENDING = sdk_sys::EVERYTHING_SORT_RUN_COUNT_ASCENDING,
257    EVERYTHING_SORT_RUN_COUNT_DESCENDING = sdk_sys::EVERYTHING_SORT_RUN_COUNT_DESCENDING,
258    EVERYTHING_SORT_DATE_RECENTLY_CHANGED_ASCENDING =
259        sdk_sys::EVERYTHING_SORT_DATE_RECENTLY_CHANGED_ASCENDING,
260    EVERYTHING_SORT_DATE_RECENTLY_CHANGED_DESCENDING =
261        sdk_sys::EVERYTHING_SORT_DATE_RECENTLY_CHANGED_DESCENDING,
262    EVERYTHING_SORT_DATE_ACCESSED_ASCENDING = sdk_sys::EVERYTHING_SORT_DATE_ACCESSED_ASCENDING,
263    EVERYTHING_SORT_DATE_ACCESSED_DESCENDING = sdk_sys::EVERYTHING_SORT_DATE_ACCESSED_DESCENDING,
264    EVERYTHING_SORT_DATE_RUN_ASCENDING = sdk_sys::EVERYTHING_SORT_DATE_RUN_ASCENDING,
265    EVERYTHING_SORT_DATE_RUN_DESCENDING = sdk_sys::EVERYTHING_SORT_DATE_RUN_DESCENDING,
266}
267
268impl Default for SortType {
269    fn default() -> Self {
270        Self::EVERYTHING_SORT_NAME_ASCENDING
271    }
272}
273
274/// The Everything_SetSort function sets how the results should be ordered.
275///
276/// # Arguments
277/// * `sort_type` - The sort type, should be one of the values named `EVERYTHING_SORT_*`.
278///
279/// # Remarks
280/// - The default sort is `EVERYTHING_SORT_NAME_ASCENDING` (1). This sort is free.
281/// - Using fast sorts is recommended, fast sorting is instant.
282/// - It is possible the sort is not supported, in which case after you have received your results you should
283///   call `Everything_GetResultListSort` to determine the sorting actually used.
284/// - This function MUST be called before `Everything_Query`.
285///
286/// # Requirements
287/// Requires Everything 1.4.1 or later.
288pub fn Everything_SetSort(sort_type: SortType) {
289    unsafe { sdk_sys::Everything_SetSort(sort_type as u32) }
290}
291
292bitflags! {
293    #[repr(transparent)] // TODO: should i?
294    #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
295    pub struct RequestFlags: u32 {
296        const EVERYTHING_REQUEST_FILE_NAME = sdk_sys::EVERYTHING_REQUEST_FILE_NAME;
297        const EVERYTHING_REQUEST_PATH = sdk_sys::EVERYTHING_REQUEST_PATH;
298        const EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME = sdk_sys::EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME;
299        const EVERYTHING_REQUEST_EXTENSION = sdk_sys::EVERYTHING_REQUEST_EXTENSION;
300        const EVERYTHING_REQUEST_SIZE = sdk_sys::EVERYTHING_REQUEST_SIZE;
301        const EVERYTHING_REQUEST_DATE_CREATED = sdk_sys::EVERYTHING_REQUEST_DATE_CREATED;
302        const EVERYTHING_REQUEST_DATE_MODIFIED = sdk_sys::EVERYTHING_REQUEST_DATE_MODIFIED;
303        const EVERYTHING_REQUEST_DATE_ACCESSED = sdk_sys::EVERYTHING_REQUEST_DATE_ACCESSED;
304        const EVERYTHING_REQUEST_ATTRIBUTES = sdk_sys::EVERYTHING_REQUEST_ATTRIBUTES;
305        const EVERYTHING_REQUEST_FILE_LIST_FILE_NAME = sdk_sys::EVERYTHING_REQUEST_FILE_LIST_FILE_NAME;
306        const EVERYTHING_REQUEST_RUN_COUNT = sdk_sys::EVERYTHING_REQUEST_RUN_COUNT;
307        const EVERYTHING_REQUEST_DATE_RUN = sdk_sys::EVERYTHING_REQUEST_DATE_RUN;
308        const EVERYTHING_REQUEST_DATE_RECENTLY_CHANGED = sdk_sys::EVERYTHING_REQUEST_DATE_RECENTLY_CHANGED;
309        const EVERYTHING_REQUEST_HIGHLIGHTED_FILE_NAME = sdk_sys::EVERYTHING_REQUEST_HIGHLIGHTED_FILE_NAME;
310        const EVERYTHING_REQUEST_HIGHLIGHTED_PATH = sdk_sys::EVERYTHING_REQUEST_HIGHLIGHTED_PATH;
311        const EVERYTHING_REQUEST_HIGHLIGHTED_FULL_PATH_AND_FILE_NAME = sdk_sys::EVERYTHING_REQUEST_HIGHLIGHTED_FULL_PATH_AND_FILE_NAME;
312    }
313}
314
315impl Default for RequestFlags {
316    fn default() -> Self {
317        Self::EVERYTHING_REQUEST_FILE_NAME | Self::EVERYTHING_REQUEST_PATH
318    }
319}
320
321/// The `Everything_SetRequestFlags` function sets the desired result data.
322///
323/// # Arguments
324/// * `request_flags` - The request flags, can be zero or more of the flags named `EVERYTHING_SORT_*`.
325///
326/// # Remarks
327/// - Make sure you include `EVERYTHING_REQUEST_FILE_NAME` and `EVERYTHING_REQUEST_PATH` if you want
328///   the result file name information returned.
329/// - The default request flags are `EVERYTHING_REQUEST_FILE_NAME` | `EVERYTHING_REQUEST_PATH` (0x00000003).
330/// - When the default flags (`EVERYTHING_REQUEST_FILE_NAME` | `EVERYTHING_REQUEST_PATH`) are used
331///   the SDK will use the old version 1 query.
332/// - When any other flags are used the new version 2 query will be tried first, and then fall back
333///   to version 1 query.
334/// - It is possible the requested data is not available, in which case after you have received
335///   your results you should call `Everything_GetResultListRequestFlags` to determine the available
336///   result data.
337/// - This function MUST be called before `Everything_Query`.
338///
339/// # Requirements
340/// Requires Everything 1.4.1 or later.
341pub fn Everything_SetRequestFlags(request_flags: RequestFlags) {
342    unsafe { sdk_sys::Everything_SetRequestFlags(request_flags.bits()) }
343}
344
345// --- read search state ---
346
347/// The `Everything_GetMatchPath` function returns the state of the match full path switch.
348///
349/// # Return
350/// Returns `true` if match full path is enabled, else `false`.
351///
352/// # Remarks
353/// - Get the internal state of the match full path switch.
354/// - The default state is `false`, or disabled.
355pub fn Everything_GetMatchPath() -> bool {
356    let enabled = unsafe { sdk_sys::Everything_GetMatchPath() };
357    lower_bool(enabled)
358}
359
360/// The `Everything_GetMatchCase` function returns the match case state.
361///
362/// # Return
363/// Returns the match case state, `true` if the match case is enabled, `false` if disabled.
364///
365/// # Remarks
366/// - Get the internal state of the match case switch.
367/// - The default state is `false`, or disabled.
368pub fn Everything_GetMatchCase() -> bool {
369    let enabled = unsafe { sdk_sys::Everything_GetMatchCase() };
370    lower_bool(enabled)
371}
372
373/// The `Everything_GetMatchWholeWord` function returns the match whole word state.
374///
375/// # Return
376/// Returns the match whole word state, `true` if the the match whole word is
377/// enabled, `false` if disabled.
378///
379/// # Remarks
380/// - The default state is `false`, or disabled.
381pub fn Everything_GetMatchWholeWord() -> bool {
382    let enabled = unsafe { sdk_sys::Everything_GetMatchWholeWord() };
383    lower_bool(enabled)
384}
385
386/// The `Everything_GetRegex` function returns the regex state.
387///
388/// # Return
389/// Returns the regex state, `true` if the the regex is enabled, `false` if disabled.
390///
391/// # Remarks
392/// - The default state is `false`, or disabled.
393pub fn Everything_GetRegex() -> bool {
394    let enabled = unsafe { sdk_sys::Everything_GetRegex() };
395    lower_bool(enabled)
396}
397
398/// The `Everything_GetMax` function returns the maximum number of results state.
399///
400/// # Return
401/// The return value is the maximum number of results state. The function returns
402/// u32::MAX (0xFFFFFFFF) if all results should be returned.
403///
404/// # Remarks
405/// - The default state is u32::MAX (0xFFFFFFFF), or all results.
406pub fn Everything_GetMax() -> u32 {
407    unsafe { sdk_sys::Everything_GetMax() }
408}
409
410/// The `Everything_GetOffset` function returns the first item offset of the available results.
411///
412/// # Return
413/// Returns the first item offset.
414///
415/// # Remarks
416/// - The default offset is 0.
417pub fn Everything_GetOffset() -> u32 {
418    unsafe { sdk_sys::Everything_GetOffset() }
419}
420
421/// The `Everything_GetSearch` function retrieves the search text to use for the next call
422/// to `Everything_Query`.
423///
424/// # Return
425/// If the function should not fail.
426///
427/// # Remarks
428/// - Get the internal state of the search text.
429/// - The default string is an empty string.
430pub fn Everything_GetSearch() -> OsString {
431    let ptr = unsafe { sdk_sys::Everything_GetSearchW() };
432    assert!(!ptr.is_null());
433    // SAFETY: now ptr is non-null, and it is null terminated string return
434    // from `Everything_GetSearchW`
435    unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string()
436}
437
438#[repr(u32)]
439#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Primitive)]
440#[allow(non_camel_case_types)]
441pub enum LastError {
442    EVERYTHING_OK = sdk_sys::EVERYTHING_OK, // no error detected
443    EVERYTHING_ERROR_MEMORY = sdk_sys::EVERYTHING_ERROR_MEMORY, // out of memory.
444    EVERYTHING_ERROR_IPC = sdk_sys::EVERYTHING_ERROR_IPC, // Everything search client is not running
445    EVERYTHING_ERROR_REGISTERCLASSEX = sdk_sys::EVERYTHING_ERROR_REGISTERCLASSEX, // unable to register window class.
446    EVERYTHING_ERROR_CREATEWINDOW = sdk_sys::EVERYTHING_ERROR_CREATEWINDOW, // unable to create listening window
447    EVERYTHING_ERROR_CREATETHREAD = sdk_sys::EVERYTHING_ERROR_CREATETHREAD, // unable to create listening thread
448    EVERYTHING_ERROR_INVALIDINDEX = sdk_sys::EVERYTHING_ERROR_INVALIDINDEX, // invalid index
449    EVERYTHING_ERROR_INVALIDCALL = sdk_sys::EVERYTHING_ERROR_INVALIDCALL,   // invalid call
450    EVERYTHING_ERROR_INVALIDREQUEST = sdk_sys::EVERYTHING_ERROR_INVALIDREQUEST, // invalid request data, request data first.
451    EVERYTHING_ERROR_INVALIDPARAMETER = sdk_sys::EVERYTHING_ERROR_INVALIDPARAMETER, // bad parameter.
452}
453
454/// The `Everything_GetLastError` function retrieves the last-error code value.
455///
456/// It will **keep** the _LAST_ error (maybe OK), unless the [`Everything_Reset`] or else is called.
457///
458/// Note that if some function was called and done successfully, the _last error_ may OR may not
459/// be set or updated to [`LastError::EVERYTHING_OK`]. The SDK makes no guarantees about this
460/// behavior.
461///
462/// So call this when the document of the api function explicitly mentions "To get extended error
463/// information, call `Everything_GetLastError`."
464pub fn Everything_GetLastError() -> LastError {
465    let last_error = unsafe { sdk_sys::Everything_GetLastError() };
466    LastError::try_from(last_error).expect("it should be a valid LastError number")
467}
468
469/// The `Everything_GetReplyWindow` function returns the current reply window for the IPC query reply.
470///
471/// # Return
472/// Returns the current reply window.
473///
474/// # Remarks
475/// - The default reply window is 0, or no reply window.
476///
477/// TODO: These functions coupled with the IPC mechanism that is `WM_COPYDATA` in Win32 API.
478/// ...
479#[cfg_attr(not(feature = "raw"), allow(dead_code))]
480pub fn Everything_GetReplyWindow() -> HWND {
481    unsafe { sdk_sys::Everything_GetReplyWindow() }
482}
483
484/// The `Everything_GetReplyID` function returns the current reply identifier for the IPC query reply.
485///
486/// # Return
487/// The return value is the current reply identifier.
488///
489/// # Remarks
490/// - The default reply identifier is 0.
491///
492/// TODO: These functions coupled with the IPC mechanism that is `WM_COPYDATA` in Win32 API.
493/// ...
494#[cfg_attr(not(feature = "raw"), allow(dead_code))]
495pub fn Everything_GetReplyID() -> u32 {
496    unsafe { sdk_sys::Everything_GetReplyID() }
497}
498
499/// The `Everything_GetSort` function returns the desired sort order for the results.
500///
501/// # Return
502/// Returns one of the sort types.
503///
504/// # Remarks
505/// - The default sort is `EVERYTHING_SORT_NAME_ASCENDING` (1)
506///
507/// # Requirements
508/// Requires Everything 1.4.1 or later.
509pub fn Everything_GetSort() -> SortType {
510    let sort_type = unsafe { sdk_sys::Everything_GetSort() };
511    SortType::try_from(sort_type).expect("it should be a valid SortType number")
512}
513
514/// The `Everything_GetRequestFlags` function returns the desired result data flags.
515///
516/// # Return
517/// Returns zero or more of the request flags.
518///
519/// # Remarks
520/// - The default request flags are `EVERYTHING_REQUEST_FILE_NAME` | `EVERYTHING_REQUEST_PATH`,
521///   that is (0x00000003).
522///
523/// # Requirements
524/// Requires Everything 1.4.1 or later.
525pub fn Everything_GetRequestFlags() -> RequestFlags {
526    let request_flags = unsafe { sdk_sys::Everything_GetRequestFlags() };
527    RequestFlags::from_bits(request_flags).expect("unknown bits should not be set")
528}
529
530// --- execute query ---
531
532/// The `Everything_Query` function executes an Everything IPC query with the current search state.
533///
534/// # Arguments
535/// * `wait` - should the function wait for the results or return immediately.
536///   Set this to `true` to send the IPC Query and wait for the results. (Normally)
537///   Set this to `false` to post the IPC Query and return immediately.
538///
539/// # Return
540/// If succeeds, return `true`, else `false`.
541/// To get extended error information, call `Everything_GetLastError`
542///
543/// # Remarks
544/// - If wait is `false` you MUST call `Everything_SetReplyWindow` before calling `Everything_Query`.
545///   Use the `Everything_IsQueryReply` function to check for query replies.
546/// - Optionally call the `Everything_Set*` functions to set the search state before
547///   calling `Everything_Query`.
548/// - The search state is not modified from a call to `Everything_Query`.
549/// - If you want to know the default search state, see `Everything_Reset` for it.
550pub fn Everything_Query(wait: bool) -> bool {
551    let wait = if wait { TRUE } else { FALSE };
552    let success = unsafe { sdk_sys::Everything_QueryW(wait) };
553    lower_bool(success)
554}
555
556// --- query reply ---
557
558/// The `Everything_IsQueryReply` function checks if the specified window message is a query reply.
559///
560/// # Arguments
561/// * `u_msg` - Specifies the message identifier. (uMsg as `UINT` in winapi)
562/// * `w_param` - Specifies additional information about the message. (wParam as `WPARAM` in winapi)
563/// * `l_param` - Specifies additional information about the message. (lParam as `LPARAM` in winapi)
564/// * `n_id` - The unique identifier specified with `Everything_SetReplyID`, or 0 for the default ID.
565///   This is the underlying value used to compare with the `dwData` member of the `COPYDATASTRUCT`
566///   if the message is `WM_COPYDATA`.
567///
568/// # Return
569/// if the message is a query reply, return `true`.
570/// if the function fails, return `false`. To get extended error information, call `Everything_GetLastError`.
571///
572/// # Remarks
573/// - This function checks if the message is a `WM_COPYDATA` message. If the message is a `WM_COPYDATA`
574///   message the function checks if the ReplyID matches the `dwData` member of the `COPYDATASTRUCT`.
575///   If they match the function makes a copy of the query results.
576/// - You MUST call `Everything_IsQueryReply` in the windows message handler to check for an IPC query
577///   reply if you call `Everything_Query` with `wait` set to `false`.
578/// - For your `WindowProc` function, if this function returns `true`, you should return `true`.
579///   Ref: [WindowProc](https://en.wikipedia.org/wiki/WindowProc)
580/// - If this function `true` you can call the other functions (like `Everything_GetResultPath`) to
581///   read the results.
582///
583/// TODO: These functions coupled with the IPC mechanism that is `WM_COPYDATA` in Win32 API.
584/// - `Everything_IsQueryReply`, `Everything_SetReplyWindow`, `Everything_GetReplyWindow`,
585///   `Everything_SetReplyID`, `Everything_GetReplyID`,
586/// - [Using Data Copy](https://learn.microsoft.com/en-us/windows/win32/dataxchg/using-data-copy)
587/// - [Windows and Messages](https://learn.microsoft.com/en-us/windows/win32/api/_winmsg/)
588/// - [Window Procedures](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-procedures)
589#[cfg_attr(not(feature = "raw"), allow(dead_code))]
590pub fn Everything_IsQueryReply(u_msg: UINT, w_param: WPARAM, l_param: LPARAM, n_id: u32) -> bool {
591    let is_reply = unsafe { sdk_sys::Everything_IsQueryReply(u_msg, w_param, l_param, n_id) };
592    lower_bool(is_reply)
593}
594
595// --- write result state ---
596
597/// The `Everything_SortResultsByPath` function sorts the current results by path, then file name.
598/// SortResultsByPath is **CPU Intensive**. Sorting by path can take several seconds.
599///
600/// # Remarks
601/// - The default result list contains no results.
602/// - Call `Everything_Query` to retrieve the result list prior to a call to `Everything_SortResultsByPath`.
603/// - For improved performance, use `Everything_SetSort`.
604pub fn Everything_SortResultsByPath() {
605    unsafe { sdk_sys::Everything_SortResultsByPath() }
606}
607
608// --- read result state ---
609
610/// The `Everything_GetNumFileResults` function returns the number of visible file results.
611///
612/// # Return
613/// Returns the number of visible file results.
614/// If the function fails the return value is 0. (weird)
615/// To get extended error information, call `Everything_GetLastError`.
616///
617/// # Remarks
618/// - You must call `Everything_Query` before calling `Everything_GetNumFileResults`.
619/// - Use [`Everything_GetTotFileResults`] to retrieve the total number of file results.
620/// - If the result offset state is 0, and the max result is u32::MAX (0xFFFFFFFF),
621///   `Everything_GetNumFileResults` will return the total number of file results
622///   and all file results will be visible.
623/// - `Everything_GetNumFileResults` is not supported when using [`Everything_SetRequestFlags`]
624pub fn Everything_GetNumFileResults() -> u32 {
625    unsafe { sdk_sys::Everything_GetNumFileResults() }
626}
627
628/// The `Everything_GetNumFolderResults` function returns the number of visible
629/// folder results.
630///
631/// # Return
632/// Returns the number of visible file results.
633/// If the function fails the return value is 0. (weird)
634/// To get extended error information, call `Everything_GetLastError`.
635///
636/// # Remarks
637/// - You must call `Everything_Query` before calling `Everything_GetNumFolderResults`.
638/// - Use [`Everything_GetTotFolderResults`] to retrieve the total number of folder results.
639/// - If the result offset state is 0, and the max result is u32::MAX (0xFFFFFFFF),
640///   `Everything_GetNumFolderResults` will return the total number of folder results and all
641///   folder results will be visible.
642/// - `Everything_GetNumFolderResults` is not supported when using [`Everything_SetRequestFlags`].
643pub fn Everything_GetNumFolderResults() -> u32 {
644    unsafe { sdk_sys::Everything_GetNumFolderResults() }
645}
646
647/// The `Everything_GetNumResults` function returns the number of visible file and
648/// folder results.
649///
650/// # Return
651/// Returns the number of visible file and folder results.
652/// If the function fails the return value is 0. (weird)
653/// To get extended error information, call `Everything_GetLastError`.
654///
655/// # Remarks
656/// - You must call `Everything_Query` before calling `Everything_GetNumResults`.
657/// - Use `Everything_GetTotResults` to retrieve the total number of file and folder results.
658/// - If the result offset state is 0, and the max result is u32::MAX (0xFFFFFFFF),
659///   `Everything_GetNumResults` will return the total number of file and folder results
660///   and all file and folder results will be visible.
661pub fn Everything_GetNumResults() -> u32 {
662    unsafe { sdk_sys::Everything_GetNumResults() }
663}
664
665/// The `Everything_GetTotFileResults` function returns the total number of file results.
666///
667/// # Return
668/// Returns the total number of file results.
669/// If the function fails the return value is 0. (weird)
670/// To get extended error information, call `Everything_GetLastError`.
671///
672/// # Remarks
673/// - You must call `Everything_Query` before calling `Everything_GetTotFileResults`.
674/// - Use `Everything_GetNumFileResults` to retrieve the number of visible file results.
675/// - Use the result offset and max result values to limit the number of visible results.
676/// - `Everything_GetTotFileResults` is not supported when using [`Everything_SetRequestFlags`].
677pub fn Everything_GetTotFileResults() -> u32 {
678    unsafe { sdk_sys::Everything_GetTotFileResults() }
679}
680
681/// The `Everything_GetTotFolderResults` function returns the total number of folder results.
682///
683/// # Return
684/// Returns the total number of folder results.
685/// If the function fails the return value is 0. (weird)
686/// To get extended error information, call `Everything_GetLastError`.
687///
688/// # Remarks
689/// - You must call `Everything_Query` before calling `Everything_GetTotFolderResults`.
690/// - Use `Everything_GetNumFolderResults` to retrieve the number of visible folder results.
691/// - Use the result offset and max result values to limit the number of visible results.
692/// - `Everything_GetTotFolderResults` is not supported when using [`Everything_SetRequestFlags`].
693pub fn Everything_GetTotFolderResults() -> u32 {
694    unsafe { sdk_sys::Everything_GetTotFolderResults() }
695}
696
697/// The `Everything_GetTotResults` function returns the total number of file and folder results.
698///
699/// # Return
700/// Returns the total number of file and folder results.
701/// If the function fails the return value is 0. (weird)
702/// To get extended error information, call `Everything_GetLastError`.
703///
704/// # Remarks
705/// - You must call `Everything_Query` before calling `Everything_GetTotResults`.
706/// - Use `Everything_GetNumResults` to retrieve the number of visible file and folder results.
707/// - Use the result offset and max result values to limit the number of visible results.
708pub fn Everything_GetTotResults() -> u32 {
709    unsafe { sdk_sys::Everything_GetTotResults() }
710}
711
712/// The `Everything_IsVolumeResult` function determines if the visible result is the root
713/// folder of a volume.
714///
715/// # Arguments
716/// * `index` - Zero based index of the visible result.
717///
718/// # Return
719/// - The function returns `true`, if the visible result is a volume. (For example: C:)
720/// - The function returns `false`, if the visible result is a folder or file.
721///   (For example: C:\ABC.123)
722/// - If the function fails the return value is `false`. (weird)
723///   To get extended error information, call `Everything_GetLastError`.
724///
725/// # Remarks
726/// - You can only call this function for a visible result. To determine if a result is
727///   visible use the `Everything_GetNumFileResults` function.
728pub fn Everything_IsVolumeResult(index: u32) -> bool {
729    let result = unsafe { sdk_sys::Everything_IsVolumeResult(index) };
730    lower_bool(result)
731}
732
733/// The `Everything_IsFolderResult` function determines if the visible result is a folder.
734///
735/// # Arguments
736/// * `index` - Zero based index of the visible result.
737///
738/// # Return
739/// - The function returns `true`, if the visible result is a folder or volume.
740///   (For example: C: or c:\WINDOWS)
741/// - The function returns `false`, if the visible result is a file.
742///   (For example: C:\ABC.123)
743/// - If the function fails the return value is `false`. (weird)
744///   To get extended error information, call `Everything_GetLastError`.
745///
746/// # Remarks
747/// - You can only call this function for a visible result. To determine if a result is
748///   visible use the `Everything_GetNumFileResults` function.
749pub fn Everything_IsFolderResult(index: u32) -> bool {
750    let result = unsafe { sdk_sys::Everything_IsFolderResult(index) };
751    lower_bool(result)
752}
753
754/// The `Everything_IsFileResult` function determines if the visible result is file.
755///
756/// # Arguments
757/// * `index` - Zero based index of the visible result.
758///
759/// # Return
760/// - The function returns `true`, if the visible result is a file.
761///   (For example: C:\ABC.123)
762/// - The function returns `false`, if the visible result is a folder or volume.
763///   (For example: C: or c:\WINDOWS)
764/// - If the function fails the return value is `false`. (weird)
765///   To get extended error information, call `Everything_GetLastError`.
766///
767/// # Remarks
768/// - You can only call this function for a visible result. To determine if a result is
769///   visible use the `Everything_GetNumFileResults` function.
770pub fn Everything_IsFileResult(index: u32) -> bool {
771    let result = unsafe { sdk_sys::Everything_IsFileResult(index) };
772    lower_bool(result)
773}
774
775/// The `Everything_GetResultFileName` function retrieves the file name part only of the
776/// visible result.
777///
778/// # Arguments
779/// * `index` - Zero based index of the visible result.
780///
781/// # Return
782/// If the function fails the return value is None.
783/// To get extended error information, call `Everything_GetLastError`.
784///
785/// # Remarks
786/// - The function is NOT faster than `Everything_GetResultFullPathName` now, as this function
787///   DO the memory copying. If you want no memory copying, you should use the no-copy ffi
788///   function [`everything_sdk_sys::Everything_GetResultFileNameW`] directly.
789/// - The function returns a pointer to an internal structure that is only valid until the next
790///   call to `Everything_Query` or `Everything_Reset`.
791/// - You can only call this function for a visible result. To determine if a result is visible
792///   use the `Everything_GetNumFileResults` function.
793pub fn Everything_GetResultFileName(index: u32) -> Option<OsString> {
794    let ptr = unsafe { sdk_sys::Everything_GetResultFileNameW(index) };
795    if ptr.is_null() {
796        None
797    } else {
798        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
799        // from `Everything_GetResultFileNameW`
800        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
801    }
802}
803
804/// The `Everything_GetResultPath` function retrieves the path part of the visible result.
805///
806/// # Arguments
807/// * `index` - Zero based index of the visible result.
808///
809/// # Return
810/// If the function fails the return value is None.
811/// To get extended error information, call `Everything_GetLastError`.
812///
813/// # Remarks
814/// - The function is NOT faster than `Everything_GetResultFullPathName` now, as this function
815///   DO the memory copying. If you want no memory copying, you should use the no-copy ffi
816///   function [`everything_sdk_sys::Everything_GetResultPathW`] directly.
817/// - The function returns a pointer to an internal structure that is only valid until the next
818///   call to `Everything_Query` or `Everything_Reset`.
819/// - You can only call this function for a visible result. To determine if a result is visible
820///   use the `Everything_GetNumFileResults` function.
821pub fn Everything_GetResultPath(index: u32) -> Option<OsString> {
822    let ptr = unsafe { sdk_sys::Everything_GetResultPathW(index) };
823    if ptr.is_null() {
824        None
825    } else {
826        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
827        // from `Everything_GetResultPathW`
828        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
829    }
830}
831
832/// The `Everything_GetResultFullPathName` function retrieves the full path and file name
833/// of the visible result.
834///
835/// # Arguments
836/// * `index` - Zero based index of the visible result.
837/// * `out_buf` - Buffer that will receive the text. If the string is as long or longer than
838///   the buffer, the string is truncated and terminated with a NULL character.
839///
840/// # Return
841/// Returns the number of wchar_t excluding the null terminator copied into lpString.
842/// If the function fails, return None. To get extended error information, call
843/// `Everything_GetLastError`.
844///
845/// # Remarks
846/// - You can only call this function for a visible result. To determine if a result is visible
847///   use the Everything_GetNumFileResults function.
848///
849/// # Requirements
850/// Requires Everything 1.4.1 or later.
851pub fn Everything_GetResultFullPathName(index: u32, out_buf: &mut [u16]) -> Option<NonZeroU32> {
852    let buf_ptr = out_buf.as_mut_ptr();
853    let buf_size = u32::try_from(out_buf.len()).expect("buf size should not be greater than u32");
854    // If lpString is not NULL, the return value is the number of wchar_t excluding
855    // the null terminator copied into lpString.
856    let number_of_wchar_without_null_terminator =
857        unsafe { sdk_sys::Everything_GetResultFullPathNameW(index, PWSTR(buf_ptr), buf_size) };
858    NonZeroU32::new(number_of_wchar_without_null_terminator)
859}
860
861/// The `Everything_GetResultFullPathNameSizeHint` function get the buffer size hint
862/// for calling `Everything_GetResultFullPathName` including the null terminator.
863/// You can new a Vec<MaybeUninit<u16>> or array in stack with this size hint as the
864/// initial capacity of the buffer `out_buf` in `Everything_GetResultFullPathName`.
865///
866/// This function is not native in Everything-SDK, but part of the functionality
867/// stripped out of the ffi function `Everything_GetResultFullPathNameW` when its
868/// out buffer pointer is set to null.
869///
870/// # Examples
871/// ```no_run
872/// use everything_sdk::raw::*;
873/// let result_index = 0;
874/// let size_hint = u32::from(Everything_GetResultFullPathNameSizeHint(result_index).unwrap());
875/// let mut buf = vec![0; size_hint as usize];
876/// let n_wchar = u32::from(Everything_GetResultFullPathName(result_index, &mut buf).unwrap());
877/// assert_eq!(size_hint, n_wchar + 1);
878/// ```
879///
880/// # Arguments
881/// * `index` - Zero based index of the visible result.
882///
883/// # Return
884/// - Returns the size of the wchar_t buffer (including null terminator) needed to
885///   store the full path and file name of the visible result.
886/// - If the function fails, return None.
887///   To get extended error information, call `Everything_GetLastError`.
888///
889/// # Remarks
890/// - You can only call this function for a visible result. To determine if a result is visible
891///   use the Everything_GetNumFileResults function.
892///
893/// # Requirements
894/// Requires Everything 1.4.1 or later.
895pub fn Everything_GetResultFullPathNameSizeHint(index: u32) -> Option<NonZeroU32> {
896    // If lpString is NULL, the return value is the number of wchar_t excluding the
897    // null terminator needed to store the full path and file name of the visible result.
898    let wchars_without_null_terminator_size_hint =
899        unsafe { sdk_sys::Everything_GetResultFullPathNameW(index, PWSTR::null(), 0) };
900    if wchars_without_null_terminator_size_hint == 0 {
901        None
902    } else {
903        let size_hint = wchars_without_null_terminator_size_hint + 1;
904        NonZeroU32::new(size_hint)
905    }
906}
907
908/// The `Everything_GetResultListSort` function returns the actual sort order for the results.
909///
910/// # Return
911/// Returns one of the sort types.
912///
913/// # Remarks
914/// - `Everything_GetResultListSort` must be called after calling `Everything_Query`.
915/// - If no desired sort order was specified the result list is sorted by
916///   [`SortType::EVERYTHING_SORT_NAME_ASCENDING`].
917/// - The result list sort may differ to the desired sort specified in `Everything_SetSort`.
918///
919/// # Requirements
920/// Maybe require Everything 1.4.1 or later indicated in source code.
921pub fn Everything_GetResultListSort() -> SortType {
922    let sort_type = unsafe { sdk_sys::Everything_GetResultListSort() };
923    SortType::try_from(sort_type).expect("it should be a valid SortType number")
924}
925
926/// The `Everything_GetResultListRequestFlags` function returns the flags of available result data.
927///
928/// # Return
929/// Returns zero or more of the request flags.
930///
931/// # Remarks
932/// - The requested result data may differ to the desired result data specified in
933///   [`Everything_SetRequestFlags`].
934///
935/// # Requirements
936/// Requires Everything 1.4.1 or later.
937pub fn Everything_GetResultListRequestFlags() -> RequestFlags {
938    let request_flags = unsafe { sdk_sys::Everything_GetResultListRequestFlags() };
939    RequestFlags::from_bits(request_flags).expect("unknown bits should not be set")
940}
941
942/// The `Everything_GetResultExtension` function retrieves the extension part of a visible
943/// result.
944///
945/// # Arguments
946/// * `index` - Zero based index of the visible result.
947///
948/// # Return
949/// If the function fails the return value is None.
950/// To get extended error information, call `Everything_GetLastError`.
951///
952/// # Remarks
953/// - You can only call this function for a visible result. To determine if a result is
954///   visible use the `Everything_GetNumResults` function.
955///
956/// # Requirements
957/// Maybe require Everything 1.4.1 or later indicated in source code.
958pub fn Everything_GetResultExtension(index: u32) -> Option<OsString> {
959    // The function returns a pointer to an internal structure that is only valid until
960    // the next call to `Everything_Query`, `Everything_Reset` or `Everything_CleanUp`.
961    let ptr = unsafe { sdk_sys::Everything_GetResultExtensionW(index) };
962    if ptr.is_null() {
963        None
964    } else {
965        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
966        // from `Everything_GetResultExtensionW`
967        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
968    }
969}
970
971/// The `Everything_GetResultSize` function retrieves the size of a visible result.
972///
973///
974/// # Arguments
975/// * `index` - Zero based index of the visible result.
976///
977/// # Return
978/// The function returns result size if successful.
979/// The function returns `None` if size information is unavailable.
980/// To get extended error information, call `Everything_GetLastError`.
981///
982/// # Remarks
983/// - `index` must be a valid visible result index. To determine if a result index is
984///   visible use the `Everything_GetNumResults` function.
985///
986/// # Requirements
987/// Requires Everything 1.4.1 or later.
988pub fn Everything_GetResultSize(index: u32) -> Option<i64> {
989    // Ref: https://github.com/retep998/winapi-rs/blob/0.3/README.md#how-do-i-create-an-instance-of-a-union
990    let mut size: LARGE_INTEGER = 0;
991    // lpSize is the pointer to a LARGE_INTEGER to hold the size of the result.
992    let success = unsafe { sdk_sys::Everything_GetResultSize(index, &mut size) };
993    match success {
994        // SAFETY: If your compiler has built-in support for 64-bit integers, use the QuadPart member
995        // to store the 64-bit integer.
996        // Ref: https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-large_integer-r1#remarks
997        // NOTE:
998        // - If request flag `EVERYTHING_REQUEST_ATTRIBUTES` is set, GetResultSize for a folder will return 0.
999        // - If not, GetResultSize for a folder will return -1. (wired)
1000        TRUE => Some(size),
1001        FALSE => None,
1002        _ => unreachable!(),
1003    }
1004}
1005
1006/// Ref: <https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime>
1007/// Ref: <https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ularge_integer-r1>
1008fn convert_filetime_to_u64(filetime: FILETIME) -> u64 {
1009    // let mut time: ULARGE_INTEGER = 0;
1010    // // Irrelevant Tips: field `u` in ULARGE_INTEGER is type error(bug), it should be ULARGE_INTEGER_u
1011    // // instead of ULARGE_INTEGER_s.
1012    // let s_mut = unsafe { time.s_mut() };
1013    // s_mut.LowPart = filetime.dwLowDateTime;
1014    // s_mut.HighPart = filetime.dwHighDateTime;
1015    // unsafe { *time.QuadPart() }
1016    unsafe { std::mem::transmute(filetime) }
1017}
1018
1019/// The `Everything_GetResultDateCreated` function retrieves the created date of a visible result.
1020///
1021/// # Arguments
1022/// * `index` - Zero based index of the visible result.
1023///
1024/// # Return
1025/// The function returns result created date (ftCreationTime) if successful.
1026/// (Similar to the u64 return value of [`std::os::windows::fs::MetadataExt::creation_time`], see
1027/// its docs for details.)
1028/// The function returns `None` if the date created information is unavailable.
1029/// To get extended error information, call `Everything_GetLastError`.
1030///
1031/// # Remarks
1032/// - `index` must be a valid visible result index. To determine if a result index is visible use
1033///   the `Everything_GetNumResults` function.
1034///
1035/// # Requirements
1036/// Requires Everything 1.4.1 or later.
1037pub fn Everything_GetResultDateCreated(index: u32) -> Option<u64> {
1038    let mut file_time = FILETIME {
1039        dwLowDateTime: 0,
1040        dwHighDateTime: 0,
1041    };
1042    // lpDateCreated is the pointer to a FILETIME to hold the created date of the result.
1043    let success = unsafe { sdk_sys::Everything_GetResultDateCreated(index, &mut file_time) };
1044    match success {
1045        TRUE => Some(convert_filetime_to_u64(file_time)),
1046        FALSE => None,
1047        _ => unreachable!(),
1048    }
1049}
1050
1051/// The `Everything_GetResultDateModified` function retrieves the modified date of a visible result.
1052///
1053/// # Arguments
1054/// * `index` - Zero based index of the visible result.
1055///
1056/// # Return
1057/// The function returns result modified date (ftLastWriteTime) if successful.
1058/// (Similar to the u64 return value of [`std::os::windows::fs::MetadataExt::last_write_time`], see
1059/// its docs for details.)
1060/// The function returns `None` if the modified date information is unavailable.
1061/// To get extended error information, call `Everything_GetLastError`.
1062///
1063/// # Remarks
1064/// - `index` must be a valid visible result index. To determine if a result index is visible use
1065///   the `Everything_GetNumResults` function.
1066///
1067/// # Requirements
1068/// Requires Everything 1.4.1 or later.
1069pub fn Everything_GetResultDateModified(index: u32) -> Option<u64> {
1070    let mut file_time = FILETIME {
1071        dwLowDateTime: 0,
1072        dwHighDateTime: 0,
1073    };
1074    // lpDateModified is the pointer to a FILETIME to hold the modified date of the result.
1075    let success = unsafe { sdk_sys::Everything_GetResultDateModified(index, &mut file_time) };
1076    match success {
1077        TRUE => Some(convert_filetime_to_u64(file_time)),
1078        FALSE => None,
1079        _ => unreachable!(),
1080    }
1081}
1082
1083/// The `Everything_GetResultDateAccessed` function retrieves the accessed date of a visible result.
1084///
1085/// # Arguments
1086/// * `index` - Zero based index of the visible result.
1087///
1088/// # Return
1089/// The function returns result accessed date (ftLastAccessTime) if successful.
1090/// (Similar to the u64 return value of [`std::os::windows::fs::MetadataExt::last_access_time`], see
1091/// its docs for details.)
1092/// The function returns `None` if the accessed date information is unavailable.
1093/// To get extended error information, call `Everything_GetLastError`.
1094///
1095/// # Remarks
1096/// - `index` must be a valid visible result index. To determine if a result index is visible use
1097///   the `Everything_GetNumResults` function.
1098///
1099/// # Requirements
1100/// Requires Everything 1.4.1 or later.
1101pub fn Everything_GetResultDateAccessed(index: u32) -> Option<u64> {
1102    let mut file_time = FILETIME {
1103        dwLowDateTime: 0,
1104        dwHighDateTime: 0,
1105    };
1106    // lpDateAccessed is the pointer to a FILETIME to hold the accessed date of the result.
1107    let success = unsafe { sdk_sys::Everything_GetResultDateAccessed(index, &mut file_time) };
1108    match success {
1109        TRUE => Some(convert_filetime_to_u64(file_time)),
1110        FALSE => None,
1111        _ => unreachable!(),
1112    }
1113}
1114
1115/// The `Everything_GetResultAttributes` function retrieves the attributes of a visible result.
1116///
1117/// Ref: <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesw>
1118///
1119/// # Arguments
1120/// * `index` - Zero based index of the visible result.
1121///
1122/// # Return
1123/// The function returns the u32 value for zero or more of FILE_ATTRIBUTE_* flags.
1124/// (You can use the constants like [`winapi::um::winnt::FILE_ATTRIBUTE_DIRECTORY`] to match it.
1125/// Ref: <https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants>)
1126/// (Similar to the u32 return value of [`std::os::windows::fs::MetadataExt::file_attributes`], see
1127/// its docs for details.)
1128/// The function returns `None` if attribute information is unavailable.
1129/// To get extended error information, call `Everything_GetLastError`.
1130///
1131/// # Remarks
1132/// - `index` must be a valid visible result index. To determine if a result index is visible use
1133///   the `Everything_GetNumResults` function.
1134///
1135/// # Requirements
1136/// Requires Everything 1.4.1 or later.
1137pub fn Everything_GetResultAttributes(index: u32) -> Option<u32> {
1138    let attr = unsafe { sdk_sys::Everything_GetResultAttributes(index) };
1139    // The function returns `INVALID_FILE_ATTRIBUTES` if attribute information is unavailable.
1140    if attr == INVALID_FILE_ATTRIBUTES {
1141        None
1142    } else {
1143        Some(attr)
1144    }
1145}
1146
1147/// The `Everything_GetResultFileListFileName` function retrieves the file list full path
1148/// and filename of the visible result.
1149///
1150/// # Arguments
1151/// * `index` - Zero based index of the visible result.
1152///
1153/// # Return
1154/// - If the function fails the return value is None.
1155///   To get extended error information, call `Everything_GetLastError`.
1156/// - If the result specified by `index` is not in a file list, then the filename returned
1157///   is an empty string.
1158///
1159/// # Remarks
1160/// - `index` must be a valid visible result index. To determine if a result is visible use
1161///   the `Everything_GetNumFileResults` function.
1162///
1163/// # Requirements
1164/// Requires Everything 1.4.1 or later.
1165pub fn Everything_GetResultFileListFileName(index: u32) -> Option<OsString> {
1166    // The function returns a pointer to an internal structure that is only valid until
1167    // the next call to `Everything_Query` or `Everything_Reset`.
1168    let ptr = unsafe { sdk_sys::Everything_GetResultFileListFileNameW(index) };
1169    if ptr.is_null() {
1170        None
1171    } else {
1172        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
1173        // from `Everything_GetResultFileListFileNameW`
1174        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
1175    }
1176}
1177
1178/// The `Everything_GetResultRunCount` function retrieves the number of times a visible
1179/// result has been run from Everything.
1180///
1181/// # Arguments
1182/// * `index` - Zero based index of the visible result.
1183///
1184/// # Return
1185/// - The function returns the number of times the result has been run from Everything.
1186///   (maybe zero?)
1187/// - The function returns 0 if the run count information is unavailable.
1188///   To get extended error information, call `Everything_GetLastError`.
1189///
1190/// # Remarks
1191/// - `index` must be a valid visible result index. To determine if a result index is visible
1192///   use the `Everything_GetNumResults` function.
1193///
1194/// # Requirements
1195/// Requires Everything 1.4.1 or later.
1196pub fn Everything_GetResultRunCount(index: u32) -> u32 {
1197    unsafe { sdk_sys::Everything_GetResultRunCount(index) }
1198}
1199
1200/// The `Everything_GetResultDateRun` function retrieves the run date of a visible result.
1201///
1202/// # Arguments
1203/// * `index` - Zero based index of the visible result.
1204///
1205/// # Return
1206/// - The function returns result run date if successful.
1207/// - The function returns `None` if the run date information is unavailable.
1208///   To get extended error information, call `Everything_GetLastError`.
1209///
1210/// # Remarks
1211/// - `index` must be a valid visible result index. To determine if a result index is visible
1212///   use the `Everything_GetNumResults` function.
1213///
1214/// # Requirements
1215/// Requires Everything 1.4.1 or later.
1216pub fn Everything_GetResultDateRun(index: u32) -> Option<u64> {
1217    let mut file_time = FILETIME {
1218        dwLowDateTime: 0,
1219        dwHighDateTime: 0,
1220    };
1221    // lpDateRun is the pointer to a FILETIME to hold the run date of the result.
1222    let success = unsafe { sdk_sys::Everything_GetResultDateRun(index, &mut file_time) };
1223    match success {
1224        TRUE => Some(convert_filetime_to_u64(file_time)),
1225        FALSE => None,
1226        _ => unreachable!(),
1227    }
1228}
1229
1230/// The `Everything_GetResultDateRecentlyChanged` function retrieves the recently changed
1231/// date of a visible result.
1232///
1233/// # Arguments
1234/// * `index` - Zero based index of the visible result.
1235///
1236/// # Return
1237/// - The function returns result run date if successful.
1238/// - The function returns `None` if the recently changed date information is unavailable.
1239///   To get extended error information, call `Everything_GetLastError`.
1240///
1241/// # Remarks
1242/// - `index` must be a valid visible result index. To determine if a result index is visible
1243///   use the `Everything_GetNumResults` function.
1244/// - The date recently changed is the date and time of when the result was changed in
1245///   the Everything index, this could be from a file creation, rename, attribute or content
1246///   change.
1247///
1248/// # Requirements
1249/// Requires Everything 1.4.1 or later.
1250pub fn Everything_GetResultDateRecentlyChanged(index: u32) -> Option<u64> {
1251    let mut file_time = FILETIME {
1252        dwLowDateTime: 0,
1253        dwHighDateTime: 0,
1254    };
1255    // lpDateRecentlyChanged is the pointer to a FILETIME to hold the recently changed date of the result.
1256    let success =
1257        unsafe { sdk_sys::Everything_GetResultDateRecentlyChanged(index, &mut file_time) };
1258    match success {
1259        TRUE => Some(convert_filetime_to_u64(file_time)),
1260        FALSE => None,
1261        _ => unreachable!(),
1262    }
1263}
1264
1265/// The `Everything_GetResultHighlightedFileName` function retrieves the highlighted file
1266/// name part of the visible result.
1267///
1268/// # Arguments
1269/// * `index` - Zero based index of the visible result.
1270///
1271/// # Return
1272/// If the function fails the return value is None.
1273/// To get extended error information, call `Everything_GetLastError`.
1274///
1275/// # Remarks
1276/// - You can only call this function for a visible result. To determine if a result is visible
1277///   use the `Everything_GetNumFileResults` function.
1278/// - Text inside a \* quote is highlighted, two consecutive \*'s is a single literal \*.
1279/// - For example, in the highlighted text: abc \*123\* the 123 part is highlighted.
1280///
1281/// # Requirements
1282/// Requires Everything 1.4.1 or later.
1283pub fn Everything_GetResultHighlightedFileName(index: u32) -> Option<OsString> {
1284    // The function returns a pointer to an internal structure that is only valid until
1285    // the next call to `Everything_Query` or `Everything_Reset`.
1286    let ptr = unsafe { sdk_sys::Everything_GetResultHighlightedFileNameW(index) };
1287    if ptr.is_null() {
1288        None
1289    } else {
1290        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
1291        // from `Everything_GetResultHighlightedFileNameW`
1292        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
1293    }
1294}
1295
1296/// The `Everything_GetResultHighlightedPath` function retrieves the highlighted path part
1297/// of the visible result.
1298///
1299/// # Arguments
1300/// * `index` - Zero based index of the visible result.
1301///
1302/// # Return
1303/// If the function fails the return value is None.
1304/// To get extended error information, call `Everything_GetLastError`.
1305///
1306/// # Remarks
1307/// - You can only call this function for a visible result. To determine if a result is visible
1308///   use the `Everything_GetNumFileResults` function.
1309/// - Text inside a \* quote is highlighted, two consecutive \*'s is a single literal \*.
1310/// - For example, in the highlighted text: abc \*123\* the 123 part is highlighted.
1311///
1312/// # Requirements
1313/// Requires Everything 1.4.1 or later.
1314pub fn Everything_GetResultHighlightedPath(index: u32) -> Option<OsString> {
1315    // The function returns a pointer to an internal structure that is only valid until
1316    // the next call to `Everything_Query` or `Everything_Reset`.
1317    let ptr = unsafe { sdk_sys::Everything_GetResultHighlightedPathW(index) };
1318    if ptr.is_null() {
1319        None
1320    } else {
1321        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
1322        // from `Everything_GetResultHighlightedPathW`
1323        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
1324    }
1325}
1326
1327/// The `Everything_GetResultHighlightedFullPathAndFileName` function retrieves the highlighted
1328/// full path and file name of the visible result.
1329///
1330/// # Arguments
1331/// * `index` - Zero based index of the visible result.
1332///
1333/// # Return
1334/// If the function fails the return value is None.
1335/// To get extended error information, call `Everything_GetLastError`.
1336///
1337/// # Remarks
1338/// - You can only call this function for a visible result. To determine if a result is visible
1339///   use the `Everything_GetNumFileResults` function.
1340/// - Text inside a \* quote is highlighted, two consecutive \*'s is a single literal \*.
1341/// - For example, in the highlighted text: abc \*123\* the 123 part is highlighted.
1342///
1343/// # Requirements
1344/// Requires Everything 1.4.1 or later.
1345pub fn Everything_GetResultHighlightedFullPathAndFileName(index: u32) -> Option<OsString> {
1346    // The function returns a pointer to an internal structure that is only valid until
1347    // the next call to `Everything_Query` or `Everything_Reset`.
1348    let ptr = unsafe { sdk_sys::Everything_GetResultHighlightedFullPathAndFileNameW(index) };
1349    if ptr.is_null() {
1350        None
1351    } else {
1352        // SAFETY: now ptr is non-null, and it is null terminated string of TCHARs return
1353        // from `Everything_GetResultHighlightedFullPathAndFileNameW`
1354        Some(unsafe { U16CStr::from_ptr_str(ptr.as_ptr()) }.to_os_string())
1355    }
1356}
1357
1358// --- reset state and free any allocated memory ---
1359
1360/// The `Everything_Reset` function resets the result list and search state to the default
1361/// state, freeing any allocated memory by the library.
1362///
1363/// # Remarks
1364/// - Calling `Everything_SetSearch` frees the old search and allocates the new search string.
1365/// - Calling `Everything_Query` frees the old result list and allocates the new result list.
1366/// - Calling `Everything_Reset` frees the current search and current result list.
1367/// - The default state:
1368///    + Everything_SetSearch("");
1369///    + Everything_SetMatchPath(false);
1370///    + Everything_SetMatchCase(false);
1371///    + Everything_SetMatchWholeWord(false);
1372///    + Everything_SetRegex(false);
1373///    + Everything_SetMax(u32::MAX);
1374///    + Everything_SetOffset(0);
1375///    + Everything_SetReplyWindow(std::ptr::null_mut());
1376///    + Everything_SetReplyID(0);
1377pub fn Everything_Reset() {
1378    unsafe { sdk_sys::Everything_Reset() }
1379}
1380
1381/// The `Everything_CleanUp` function frees any allocated memory by the library.
1382///
1383/// # Remarks
1384/// - You should call `Everything_CleanUp` to free any memory allocated by the Everything SDK.
1385/// - `Everything_CleanUp` should be the last call to the Everything SDK.
1386/// - Call `Everything_Reset` to free any allocated memory for the current search and results.
1387/// - `Everything_Reset` will also reset the search and result state to their defaults.
1388/// - Calling `Everything_SetSearch` frees the old search and allocates the new search string.
1389/// - Calling `Everything_Query` frees the old result list and allocates the new result list.
1390pub fn Everything_CleanUp() {
1391    unsafe { sdk_sys::Everything_CleanUp() }
1392}
1393
1394/// The `Everything_GetMajorVersion` function retrieves the major version number of Everything.
1395///
1396/// # Return
1397/// - The function returns the major version number.
1398/// - The function returns 0 if major version information is unavailable.
1399///   To get extended error information, call `Everything_GetLastError`.
1400///
1401/// # Remarks
1402/// - Everything uses the version format: `<major>.<minor>.<revision>.<build>`
1403/// - The build part is incremental and unique for all Everything versions.
1404///
1405/// # Requirements
1406/// Requires Everything 1.0.0.0 or later.
1407pub fn Everything_GetMajorVersion() -> Option<u32> {
1408    zero_or_ipc_error(unsafe { sdk_sys::Everything_GetMajorVersion() })
1409}
1410
1411/// The `Everything_GetMinorVersion` function retrieves the minor version number of Everything.
1412///
1413/// # Return
1414/// - The function returns the minor version number.
1415/// - The function returns 0 if minor version information is unavailable.
1416///   To get extended error information, call `Everything_GetLastError`.
1417///
1418/// # Remarks
1419/// - Everything uses the version format: `<major>.<minor>.<revision>.<build>`
1420/// - The build part is incremental and unique for all Everything versions.
1421///
1422/// # Requirements
1423/// Requires Everything 1.0.0.0 or later.
1424pub fn Everything_GetMinorVersion() -> Option<u32> {
1425    zero_or_ipc_error(unsafe { sdk_sys::Everything_GetMinorVersion() })
1426}
1427
1428/// The `Everything_GetRevision` function retrieves the revision number of Everything.
1429///
1430/// # Return
1431/// - The function returns the revision number.
1432/// - The function returns 0 if revision information is unavailable.
1433///   To get extended error information, call `Everything_GetLastError`.
1434///
1435/// # Remarks
1436/// - Everything uses the version format: `<major>.<minor>.<revision>.<build>`
1437/// - The build part is incremental and unique for all Everything versions.
1438///
1439/// # Requirements
1440/// Requires Everything 1.0.0.0 or later.
1441pub fn Everything_GetRevision() -> Option<u32> {
1442    zero_or_ipc_error(unsafe { sdk_sys::Everything_GetRevision() })
1443}
1444
1445/// The `Everything_GetBuildNumber` function retrieves the build number of Everything.
1446///
1447/// # Return
1448/// - The function returns the build number.
1449/// - The function returns 0 if build information is unavailable.
1450///   To get extended error information, call `Everything_GetLastError`.
1451///
1452/// # Remarks
1453/// - Everything uses the version format: `<major>.<minor>.<revision>.<build>`
1454/// - The build part is incremental and unique for all Everything versions.
1455///
1456/// # Requirements
1457/// Requires Everything 1.0.0.0 or later.
1458pub fn Everything_GetBuildNumber() -> Option<u32> {
1459    zero_or_ipc_error(unsafe { sdk_sys::Everything_GetBuildNumber() })
1460}
1461
1462/// The `Everything_Exit` function requests Everything to exit.
1463///
1464/// # Return
1465/// - The function returns `true` if the exit request was successful.
1466/// - The function returns `false` if the request failed.
1467///   To get extended error information, call `Everything_GetLastError`.
1468///
1469/// # Remarks
1470/// - Request Everything to save settings and data to disk and exit.
1471///
1472/// # Requirements
1473/// Requires Everything 1.4.1 or later.
1474pub fn Everything_Exit() -> Option<bool> {
1475    let exit_success = unsafe { sdk_sys::Everything_Exit() };
1476    lower_bool_or_ipc_error(exit_success)
1477}
1478
1479/// Try closing `Everything` client and stoping `Everything` Windows service. (Unstable)
1480///
1481/// can be called as admin or standard user.
1482/// will self elevate if needed.
1483/// (this API NOT in .def)
1484///
1485/// # Return
1486/// If it does not make an attempt (that is it does nothing), return `false`.
1487/// If it makes an attempt (that is it calls the ffi function), whether it fails or not, return `true`.
1488#[cfg_attr(not(feature = "raw"), allow(dead_code))]
1489pub fn Everything_MSIExitAndStopService() -> bool {
1490    let result = unsafe { sdk_sys::Everything_MSIExitAndStopService(std::ptr::null_mut()) };
1491    match result {
1492        0 => true,
1493        1 => false,
1494        _ => unreachable!(),
1495    }
1496}
1497
1498/// Try starting `Everything` Windows service. (Unstable)
1499///
1500/// MUST be called as an admin.
1501/// (this API NOT in .def)
1502///
1503/// # Return
1504/// If it does not make an attempt (that is it does nothing), return `false`.
1505/// If it makes an attempt(that is it calls the ffi function), whether it fails or not, return `true`.
1506#[cfg_attr(not(feature = "raw"), allow(dead_code))]
1507pub fn Everything_MSIStartService() -> bool {
1508    let result = unsafe { sdk_sys::Everything_MSIStartService(std::ptr::null_mut()) };
1509    match result {
1510        0 => true,
1511        1 => false,
1512        _ => unreachable!(),
1513    }
1514}
1515
1516/// The `Everything_IsDBLoaded` function checks if the database has been fully loaded.
1517///
1518/// # Return
1519/// - The function returns `true` if the Everything database is fully loaded.
1520/// - The function returns `false` if the database has not fully loaded or if an error occurred.
1521///   To get extended error information, call `Everything_GetLastError`.
1522///
1523/// # Remarks
1524/// - When Everything is loading, any queries will appear to return no results.
1525/// - Use `Everything_IsDBLoaded` to determine if the database has been loaded before
1526///   performing a query.
1527///
1528/// # Requirements
1529/// Requires Everything 1.4.1 or later.
1530pub fn Everything_IsDBLoaded() -> Option<bool> {
1531    let is_db_loaded = unsafe { sdk_sys::Everything_IsDBLoaded() };
1532    lower_bool_or_ipc_error(is_db_loaded)
1533}
1534
1535/// The `Everything_IsAdmin` function checks if Everything is running as administrator
1536/// or as a standard user.
1537///
1538/// # Return
1539/// - The function returns `true` if the Everything is running as an administrator.
1540/// - The function returns `false` if Everything is running as a standard user OR an error
1541///   occurred. (weird)
1542///   To get extended error information, call `Everything_GetLastError`.
1543///
1544/// # Requirements
1545/// Requires Everything 1.4.1 or later.
1546pub fn Everything_IsAdmin() -> Option<bool> {
1547    let is_admin = unsafe { sdk_sys::Everything_IsAdmin() };
1548    lower_bool_or_ipc_error(is_admin)
1549}
1550
1551/// The `Everything_IsAppData` function checks if Everything is saving settings and
1552/// data to `%APPDATA%\Everything` or to the same location as the `Everything.exe`.
1553///
1554/// # Return
1555/// - The function returns `true` if settings and data are saved in `%APPDATA%\Everything`.
1556/// - The function returns `false` if settings and data are saved to the same location
1557///   as the `Everything.exe` or if an error occurred. (weird)
1558///   To get extended error information, call `Everything_GetLastError`.
1559///
1560/// # Requirements
1561/// Requires Everything 1.4.1 or later.
1562pub fn Everything_IsAppData() -> Option<bool> {
1563    let is_app_data = unsafe { sdk_sys::Everything_IsAppData() };
1564    lower_bool_or_ipc_error(is_app_data)
1565}
1566
1567/// The `Everything_RebuildDB` function requests Everything to forcefully rebuild
1568/// the Everything index.
1569///
1570/// # Return
1571/// - The function returns `true` if the request to forcefully rebuild the Everything
1572///   index was successful.
1573/// - The function returns `false` if an error occurred.
1574///   To get extended error information, call `Everything_GetLastError`.
1575///
1576/// # Remarks
1577/// - Requesting a rebuild will mark all indexes as dirty and start the rebuild process.
1578/// - Use `Everything_IsDBLoaded` to determine if the database has been rebuilt before
1579///   performing a query.
1580///
1581/// # Requirements
1582/// Requires Everything 1.4.1 or later.
1583pub fn Everything_RebuildDB() -> Option<bool> {
1584    let success = unsafe { sdk_sys::Everything_RebuildDB() };
1585    lower_bool_or_ipc_error(success)
1586}
1587
1588/// The `Everything_UpdateAllFolderIndexes` function requests Everything to rescan all
1589/// folder indexes.
1590///
1591/// # Return
1592/// - The function returns `true` if the request to rescan all folder indexes was successful.
1593/// - The function returns `false` if an error occurred.
1594///   To get extended error information, call `Everything_GetLastError`.
1595///
1596/// # Remarks
1597/// - Everything will begin updating all folder indexes in the background.
1598///
1599/// # Requirements
1600/// Requires Everything 1.4.1 or later.
1601pub fn Everything_UpdateAllFolderIndexes() -> Option<bool> {
1602    let success = unsafe { sdk_sys::Everything_UpdateAllFolderIndexes() };
1603    lower_bool_or_ipc_error(success)
1604}
1605
1606/// The `Everything_SaveDB` function requests Everything to save the index to disk.
1607///
1608/// # Return
1609/// - The function returns `true` if the request to save the Everything index to disk
1610///   was successful.
1611/// - The function returns `false` if an error occurred.
1612///   To get extended error information, call `Everything_GetLastError`.
1613///
1614/// # Remarks
1615/// - The index is only saved to disk when you exit Everything.
1616/// - Call `Everything_SaveDB` to write the index to the file `Everything.db`
1617///
1618/// # Requirements
1619/// Requires Everything 1.4.1 or later.
1620pub fn Everything_SaveDB() -> Option<bool> {
1621    // flush index to disk
1622    let success = unsafe { sdk_sys::Everything_SaveDB() };
1623    lower_bool_or_ipc_error(success)
1624}
1625
1626/// The `Everything_SaveRunHistory` function requests Everything to save the run history
1627/// to disk.
1628///
1629/// # Return
1630/// - The function returns `true` if the request to save the run history to disk
1631///   was successful.
1632/// - The function returns `false` if an error occurred.
1633///   To get extended error information, call `Everything_GetLastError`.
1634///
1635/// # Remarks
1636/// - The run history is only saved to disk when you close an Everything search window or
1637///   exit Everything.
1638/// - Call `Everything_RunHistory` to write the run history to the file `Run History.csv`
1639///
1640/// # Requirements
1641/// Requires Everything 1.4.1 or later.
1642pub fn Everything_SaveRunHistory() -> Option<bool> {
1643    // flush run history to disk
1644    let success = unsafe { sdk_sys::Everything_SaveRunHistory() };
1645    lower_bool_or_ipc_error(success)
1646}
1647
1648/// The `Everything_DeleteRunHistory` function deletes all run history.
1649///
1650/// # Return
1651/// - The function returns `true` if run history is cleared.
1652/// - The function returns `false` if an error occurred.
1653///   To get extended error information, call `Everything_GetLastError`.
1654///
1655/// # Remarks
1656/// - Calling this function will clear all run history from memory and disk.
1657///
1658/// # Requirements
1659/// Requires Everything 1.4.1 or later.
1660pub fn Everything_DeleteRunHistory() -> Option<bool> {
1661    // clear run history
1662    let success = unsafe { sdk_sys::Everything_DeleteRunHistory() };
1663    lower_bool_or_ipc_error(success)
1664}
1665
1666#[repr(u32)]
1667#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Primitive)]
1668#[allow(non_camel_case_types)]
1669pub enum TargetMachine {
1670    EVERYTHING_TARGET_MACHINE_X86 = sdk_sys::EVERYTHING_TARGET_MACHINE_X86, // Target machine is x86 (32 bit).
1671    EVERYTHING_TARGET_MACHINE_X64 = sdk_sys::EVERYTHING_TARGET_MACHINE_X64, // Target machine is x64 (64 bit).
1672    EVERYTHING_TARGET_MACHINE_ARM = sdk_sys::EVERYTHING_TARGET_MACHINE_ARM, // Target machine is ARM.
1673}
1674
1675impl Display for TargetMachine {
1676    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1677        match self {
1678            TargetMachine::EVERYTHING_TARGET_MACHINE_X86 => write!(f, "x86"),
1679            TargetMachine::EVERYTHING_TARGET_MACHINE_X64 => write!(f, "x64"),
1680            TargetMachine::EVERYTHING_TARGET_MACHINE_ARM => write!(f, "arm"),
1681        }
1682    }
1683}
1684
1685/// The `Everything_GetTargetMachine` function retrieves the target machine of Everything.
1686///
1687/// # Return
1688/// - The function returns one of the following:
1689///    + `EVERYTHING_TARGET_MACHINE_X86` (1) -> Target machine is x86 (32 bit).
1690///    + `EVERYTHING_TARGET_MACHINE_X64` (2) -> Target machine is x64 (64 bit).
1691///    + `EVERYTHING_TARGET_MACHINE_ARM` (3) -> Target machine is ARM.
1692/// - The function returns `None` if target machine information is unavailable.
1693///   To get extended error information, call `Everything_GetLastError`.
1694///
1695/// # Remarks
1696/// - Everything uses the version format: `<major>.<minor>.<revision>.<build>`
1697/// - The build part is incremental and unique for all Everything versions.
1698///
1699/// # Requirements
1700/// Requires Everything 1.4.0 or later. (Maybe 1.4.1 or later indicated in source code)
1701pub fn Everything_GetTargetMachine() -> Option<TargetMachine> {
1702    // The function returns 0 if target machine information is unavailable.
1703    let target = unsafe { sdk_sys::Everything_GetTargetMachine() };
1704    match target {
1705        0 => None,
1706        sdk_sys::EVERYTHING_TARGET_MACHINE_X86 => {
1707            Some(TargetMachine::EVERYTHING_TARGET_MACHINE_X86)
1708        }
1709        sdk_sys::EVERYTHING_TARGET_MACHINE_X64 => {
1710            Some(TargetMachine::EVERYTHING_TARGET_MACHINE_X64)
1711        }
1712        sdk_sys::EVERYTHING_TARGET_MACHINE_ARM => {
1713            Some(TargetMachine::EVERYTHING_TARGET_MACHINE_ARM)
1714        }
1715        _ => unreachable!(),
1716    }
1717}
1718
1719/// The `Everything_IsFastSort` function checks if the specified file information is indexed
1720/// and has fast sort enabled.
1721///
1722/// # Arguments
1723/// * `sort_type` - The sort type, should be one of the values named `EVERYTHING_SORT_*`.
1724///
1725/// # Return
1726/// - The function returns `true` if the specified information is indexed and has fast sort enabled.
1727/// - The function returns `false` if the specified information does not have fast sort enabled or
1728///   if an error occurred. To get extended error information, call `Everything_GetLastError`.
1729///
1730/// # Remarks
1731/// - The following sort types are always fast sort types:
1732///    + `EVERYTHING_SORT_NAME_ASCENDING` (1) -> Name ascending
1733///    + `EVERYTHING_SORT_NAME_DESCENDING` (2) -> Name descending
1734///    + `EVERYTHING_SORT_RUN_COUNT_ASCENDING` (19) -> Run count ascending
1735///    + `EVERYTHING_SORT_RUN_COUNT_DESCENDING` (20) -> Run count descending
1736///    + `EVERYTHING_SORT_DATE_RECENTLY_CHANGED_ASCENDING` (21) -> Recently changed ascending
1737///    + `EVERYTHING_SORT_DATE_RECENTLY_CHANGED_DESCENDING` (22) -> Recently changed descending
1738///    + `EVERYTHING_SORT_DATE_RUN_ASCENDING` (25) -> Date run ascending
1739///    + `EVERYTHING_SORT_DATE_RUN_DESCENDING` (26) -> Date run descending
1740///
1741/// # Requirements
1742/// Requires Everything 1.4.1 or later. (Maybe 1.4.1.859 or later indicated in source code)
1743pub fn Everything_IsFastSort(sort_type: SortType) -> Option<bool> {
1744    let is_fast_sort = unsafe { sdk_sys::Everything_IsFastSort(sort_type as u32) };
1745    lower_bool_or_ipc_error(is_fast_sort)
1746}
1747
1748#[repr(u32)]
1749#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Primitive)]
1750#[allow(non_camel_case_types)]
1751pub enum FileInfoType {
1752    EVERYTHING_IPC_FILE_INFO_FILE_SIZE = 1,     // File size
1753    EVERYTHING_IPC_FILE_INFO_FOLDER_SIZE = 2,   // Folder size
1754    EVERYTHING_IPC_FILE_INFO_DATE_CREATED = 3,  // Date created
1755    EVERYTHING_IPC_FILE_INFO_DATE_MODIFIED = 4, // Date modified
1756    EVERYTHING_IPC_FILE_INFO_DATE_ACCESSED = 5, // Date accessed
1757    EVERYTHING_IPC_FILE_INFO_ATTRIBUTES = 6,    // Attributes
1758}
1759
1760/// The `Everything_IsFileInfoIndexed` function checks if the specified file information
1761/// is indexed.
1762///
1763/// # Arguments
1764/// * `file_info_type` - The file info type, should be one of the values
1765///   named `EVERYTHING_IPC_FILE_INFO_*`.
1766///
1767/// # Return
1768/// - The function returns `true` if the specified information is indexed.
1769/// - The function returns `false` if the specified information is not indexed OR if
1770///   an error occurred. (weird)
1771///   To get extended error information, call `Everything_GetLastError`.
1772///
1773/// # Requirements
1774/// Requires Everything 1.4.1 or later. (Maybe 1.4.1.859 or later indicated in source code)
1775pub fn Everything_IsFileInfoIndexed(file_info_type: FileInfoType) -> Option<bool> {
1776    let is_file_info_indexed =
1777        unsafe { sdk_sys::Everything_IsFileInfoIndexed(file_info_type as u32) };
1778    lower_bool_or_ipc_error(is_file_info_indexed)
1779}
1780
1781/// The `Everything_GetRunCountFromFileName` function gets the run count from a specified
1782/// file in the Everything index by file name.
1783///
1784/// # Arguments
1785/// * `file_name` - An os string that specifies a fully qualified file name in
1786///   the Everything index.
1787///
1788/// # Return
1789/// - The function returns the number of times the file has been run from Everything.
1790///   (maybe zero?)
1791/// - The function returns 0 if an error occurred.
1792///   To get extended error information, call `Everything_GetLastError`.
1793///
1794/// # Remarks
1795/// - If you want to do one less memory copy (from OsStr to "valid" UTF-16 u16 array), you
1796///   should use [`everything_sdk_sys::Everything_GetRunCountFromFileName`] directly.
1797///
1798/// # Requirements
1799/// Requires Everything 1.4.1 or later.
1800pub fn Everything_GetRunCountFromFileName(file_name: impl AsRef<OsStr>) -> Option<u32> {
1801    let name = U16CString::from_os_str(file_name).expect("the nul value only in the end");
1802    let run_count = unsafe { sdk_sys::Everything_GetRunCountFromFileNameW(PCWSTR(name.as_ptr())) };
1803    // FIX: if run count is zero, last error will not set OK(0) in C code, what should I do?
1804    zero_or_ipc_error(run_count)
1805}
1806
1807/// The `Everything_SetRunCountFromFileName` function sets the run count for a specified
1808/// file in the Everything index by file name.
1809///
1810/// # Arguments
1811/// * `file_name` - An os string that specifies a fully qualified file name in
1812///   the Everything index.
1813/// * `run_count` - The new run count.
1814///
1815/// # Return
1816/// - The function returns `true` if successful.
1817/// - The function returns 0 if an error occurred.
1818///   To get extended error information, call `Everything_GetLastError`.
1819///
1820/// # Remarks
1821/// - Set the run count to 0 to remove any run history information for the specified file.
1822/// - The file does not have to exist. When the file is created it will have the correct
1823///   run history.
1824/// - Run history information is preserved between file deletion and creation.
1825/// - Calling this function will update the date run to the current time for the specified
1826///   file.
1827///
1828/// # Requirements
1829/// Requires Everything 1.4.1 or later.
1830pub fn Everything_SetRunCountFromFileName(file_name: impl AsRef<OsStr>, run_count: u32) -> bool {
1831    let name = U16CString::from_os_str(file_name).expect("the nul value only in the end");
1832    // set a file to show higher in the results by setting an exaggerated run count
1833    let success =
1834        unsafe { sdk_sys::Everything_SetRunCountFromFileNameW(PCWSTR(name.as_ptr()), run_count) };
1835    lower_bool(success)
1836}
1837
1838/// The `Everything_IncRunCountFromFileName` function increments the run count by one for
1839/// a specified file in the Everything by file name.
1840///
1841/// # Arguments
1842/// * `file_name` - An os string that specifies a fully qualified file name in the Everything index.
1843///
1844/// # Return
1845/// - The function returns the new run count for the specifed file.
1846/// - The function returns 0 if an error occurred.
1847///   To get extended error information, call `Everything_GetLastError`.
1848///
1849/// # Remarks
1850/// - The file does not have to exist. When the file is created it will have the correct
1851///   run history.
1852/// - Run history information is preserved between file deletion and creation.
1853/// - Calling this function will update the date run to the current time for the specified
1854///   file.
1855/// - Incrementing a file with a run count of u32::MAX (4294967295 / 0xffffffff) will
1856///   do nothing.
1857///
1858/// # Requirements
1859/// Requires Everything 1.4.1 or later.
1860pub fn Everything_IncRunCountFromFileName(file_name: impl AsRef<OsStr>) -> Option<NonZeroU32> {
1861    let name = U16CString::from_os_str(file_name).expect("the nul value only in the end");
1862    // increment the run count in Everything.
1863    let new_run_count =
1864        unsafe { sdk_sys::Everything_IncRunCountFromFileNameW(PCWSTR(name.as_ptr())) };
1865    if new_run_count == 0 {
1866        match Everything_GetLastError() {
1867            LastError::EVERYTHING_ERROR_IPC => None,
1868            _ => unreachable!(),
1869        }
1870    } else {
1871        Some(NonZeroU32::new(new_run_count).unwrap())
1872    }
1873}
1874
1875/// The `Everything_SdkVerison` function gets this SDK version defined in constant value
1876/// [`everything_sdk_sys::EVERYTHING_SDK_VERSION`].
1877#[cfg_attr(not(feature = "raw"), allow(dead_code))]
1878pub const fn Everything_SdkVerison() -> u32 {
1879    sdk_sys::EVERYTHING_SDK_VERSION
1880}