Skip to main content

SCRIPT

Constant SCRIPT 

Source
pub const SCRIPT: &str = "# Windows PowerShell 5.1; fixed code, JSON request on stdin, no user code evaluation.\n$ErrorActionPreference = \'Stop\'\n$ProgressPreference = \'SilentlyContinue\'\n[Console]::InputEncoding = New-Object System.Text.UTF8Encoding($false)\n[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)\n$app = $null\n$failed = $false\ntry {\n    $request = [Console]::In.ReadToEnd() | ConvertFrom-Json\n    if ($request.operation -notin @(\'probe\', \'notebooks\', \'sections\', \'pages\', \'search\', \'read\', \'scan\')) {\n        throw [ArgumentException]::new(\'Unknown OneNote operation.\')\n    }\n    $app = New-Object -ComObject OneNote.Application\n    [string]$xml = \'\'\n    # xs2013 = 2; use a fixed schema version on every call.\n    switch ($request.operation) {\n        { $_ -in \'probe\', \'notebooks\' } { $app.GetHierarchy(\'\', 2, [ref]$xml, 2) }\n        \'sections\' { $app.GetHierarchy([string]$request.scope, 3, [ref]$xml, 2) }\n        \'pages\' { $app.GetHierarchy([string]$request.scope, 4, [ref]$xml, 2) }\n        \'search\' {\n            $searchService = Get-Service -Name WSearch -ErrorAction SilentlyContinue\n            if ($null -eq $searchService -or $searchService.Status -ne \'Running\') {\n                throw \'OneNote search requires the Windows Search (WSearch) service. Start Windows Search and retry. Notebook listing and page reading do not require it.\'\n            }\n            # Include unindexed metadata so Rust can report incomplete indexing;\n            # those pages are NOT necessarily matches and must be filtered there.\n            $app.FindPages([string]$request.scope, [string]$request.query, [ref]$xml, $true, $false, 2)\n        }\n        \'scan\' {\n            if ($request.scan_limit -lt 1 -or $request.scan_limit -gt 500 -or $request.scan_offset -lt 0 -or $request.scan_offset -gt 1000000) {\n                throw [ArgumentException]::new(\'Invalid scan bounds.\')\n            }\n            $clock = [Diagnostics.Stopwatch]::StartNew()\n            $app.GetHierarchy([string]$request.scope, 4, [ref]$xml, 2)\n            # Leave headroom for JSON escaping within the 32 MiB bridge cap.\n            $budget = 4 * 1024 * 1024\n            if ($xml.Length -gt $budget) { throw \'Scan hierarchy is too large; narrow --scope.\' }\n            $doc = New-Object Xml.XmlDocument\n            $doc.XmlResolver = $null\n            $settings = New-Object Xml.XmlReaderSettings\n            $settings.DtdProcessing = [Xml.DtdProcessing]::Prohibit\n            $reader = [Xml.XmlReader]::Create((New-Object IO.StringReader($xml)), $settings)\n            try { $doc.Load($reader) } finally { $reader.Dispose() }\n            $ns = New-Object Xml.XmlNamespaceManager($doc.NameTable)\n            $ns.AddNamespace(\'one\', \'http://schemas.microsoft.com/office/onenote/2013/onenote\')\n            if ($doc.DocumentElement.NamespaceURI -ne $ns.LookupNamespace(\'one\')) { throw \'Unexpected OneNote XML namespace.\' }\n            $visible = \"not(ancestor-or-self::*[@isRecycleBin=\'true\' or @isInRecycleBin=\'true\'])\"\n            $locked = @($doc.SelectNodes(\"//one:Section[@locked=\'true\' and $visible]\", $ns)).Count\n            $candidates = @($doc.SelectNodes(\"//one:Page[$visible and not(ancestor-or-self::*[@locked=\'true\'])]\", $ns))\n            $pages = New-Object \'Collections.Generic.List[object]\'\n            $errors = New-Object \'Collections.Generic.List[object]\'\n            $position = [int]$request.scan_offset\n            $attempted = 0\n            $used = $xml.Length\n            while ($position -lt $candidates.Count -and $attempted -lt $request.scan_limit -and $clock.Elapsed.TotalSeconds -lt 20) {\n                $id = $candidates[$position].GetAttribute(\'ID\')\n                if ([string]::IsNullOrEmpty($id)) { throw \'OneNote returned a page without an ID.\' }\n                [string]$content = \'\'\n                try {\n                    $app.GetPageContent($id, [ref]$content, 0, 2)\n                    if ($content.Length -gt $budget - $xml.Length) {\n                        $errors.Add(@{id=$id;reason=\'page_too_large\'})\n                    } elseif ($used + $content.Length -gt $budget) {\n                        break\n                    } else {\n                        $pages.Add(@{id=$id;xml=$content})\n                        $used += $content.Length\n                    }\n                } catch {\n                    $errors.Add(@{id=$id;reason=\'unreadable\'})\n                }\n                $position++\n                $attempted++\n            }\n            $next = if ($position -lt $candidates.Count) { $position } else { $null }\n            $scanResult = @{xml=$xml;pages=$pages.ToArray();skipped_pages=$errors.ToArray();skipped_locked_sections=$locked;\n                scanned_pages=$pages.Count;attempted_pages=$attempted;candidate_pages=$candidates.Count;\n                scan_offset=[int]$request.scan_offset;next_scan_offset=$next}\n        }\n        \'read\' { $app.GetPageContent([string]$request.id, [ref]$xml, 0, 2) }\n    }\n    $result = if ($request.operation -eq \'scan\') { $scanResult } else { @{xml=$xml} }\n} catch {\n    $failed = $true\n    $kind = \'desktop_error\'\n    $message = $_.Exception.Message\n    $exception = $_.Exception\n    while ($null -ne $exception.InnerException) { $exception = $exception.InnerException }\n    if ($exception -is [ArgumentException]) { $kind = \'invalid_input\' }\n    if ($null -eq $app -and $kind -ne \'invalid_input\') {\n        $message = \'Cannot connect to OneNote.Application. Install Windows OneNote desktop, open it under this Windows user, and complete any setup prompts. \' + $message\n    } elseif ($kind -eq \'desktop_error\' -and $exception.HResult -eq -2147467259) {\n        $message += \' Open OneNote in the Windows desktop session, complete first-run sign-in, and open a notebook before retrying.\'\n    }\n    if ((\'{0:X8}\' -f $exception.HResult) -eq \'8004201B\') {\n        $message += \' This section is password-protected. Unlock it in OneNote desktop and retry.\'\n    }\n    $result = @{error=@{kind=$kind; message=$message}}\n} finally {\n    if ($null -ne $app -and [Runtime.InteropServices.Marshal]::IsComObject($app)) {\n        [void][Runtime.InteropServices.Marshal]::ReleaseComObject($app)\n    }\n    # Never quit the user\'s OneNote application.\n}\n$result | ConvertTo-Json -Depth 8 -Compress\nif ($failed) { exit 1 }\n";