# 機能設計書 104-ConPTY (Pseudo Console)

## 概要

本ドキュメントは、Windows Pseudo Console (ConPTY) API の実装について記述する。ConPTYは、アプリケーションがCUIプロセスの入出力を制御できるようにするWindows APIであり、Windows Terminalのようなターミナルエミュレータがconhost.exeを介してシェルプロセスと通信するための基盤技術である。

### 本機能の処理概要

**業務上の目的・背景**：従来のWindows Console APIでは、ターミナルエミュレータが独自のレンダリングを行いつつCUIアプリケーションをホストすることが困難だった。ConPTYは、UTF-8/VTシーケンスベースのパイプを通じて入出力を行うPseudo Console（擬似コンソール）を提供し、モダンなターミナルアプリケーションの実現を可能にする。

**機能の利用シーン**：Windows Terminalが新しいタブやペインを開く際、ConPTYを作成してシェルプロセス(cmd.exe, PowerShell等)を起動する。ターミナルの入力はConPTYのhInputパイプに書き込まれ、出力はhOutputパイプから読み出される。

**主要な処理内容**：
1. ConPTYの作成（ConptyCreatePseudoConsole）：conhost.exeを--headlessモードで起動し、パイプ接続を確立する
2. ConPTYのリサイズ（ConptyResizePseudoConsole）：シグナルパイプ経由でウィンドウサイズ変更を通知する
3. ConPTYのクリア（ConptyClearPseudoConsole）：バッファクリアをシグナルパイプ経由で指示する
4. ConPTYの表示/非表示（ConptyShowHidePseudoConsole）：内部HWNDの状態同期を行う
5. ConPTYの親ウィンドウ再設定（ConptyReparentPseudoConsole）：GetConsoleWindow()の応答を制御する
6. ConPTYのクローズ（ConptyClosePseudoConsole）：全ハンドルを閉じてconhostを終了させる

**関連システム・外部連携**：conhost.exe / OpenConsole.exe、ConDrvカーネルドライバ、CreateProcess API。

**権限による制御**：ConptyCreatePseudoConsoleAsUserではユーザートークンを指定可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | TermControl（ターミナル表示） | 主機能 | ConPTYを使用したシェルプロセスとの接続管理 |

## 機能種別

システムAPI / プロセス間通信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| size | COORD | Yes | 擬似コンソールのサイズ(文字数) | X,Yともに正の値 |
| hInput | HANDLE | Yes | 入力用パイプハンドル | 有効なハンドル |
| hOutput | HANDLE | Yes | 出力用パイプハンドル | 有効なハンドル |
| dwFlags | DWORD | No | 作成フラグ | PSEUDOCONSOLE_INHERIT_CURSOR等 |
| hToken | HANDLE | No | ユーザートークン | INVALID_HANDLE_VALUEでデフォルト |

### 入力データソース

- ターミナルアプリケーションからのAPI呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| phPC | HPCON* | 作成されたPseudoConsoleのハンドル |
| HRESULT | HRESULT | 操作結果 |

### 出力先

- 呼び出し元アプリケーションへのハンドル返却

## 処理フロー

### 処理シーケンス

```
1. ConPTY作成 (_CreatePseudoConsole)
   └─ サーバーハンドル作成 (CreateServerHandle)
      └─ リファレンスハンドル作成 (CreateClientHandle)
         └─ シグナルパイプ作成 (CreatePipe)
            └─ コマンドライン構築 (conhost --headless ...)
               └─ プロセス作成 (CreateProcessAsUserW)
                  └─ PseudoConsole構造体にハンドル格納

2. リサイズ (_ResizePseudoConsole)
   └─ PTY_SIGNAL_RESIZE_WINDOW + サイズ情報をシグナルパイプに書き込み

3. クローズ (_ClosePseudoConsoleMembers)
   └─ hSignal, hPtyReference, hConPtyProcess を順にCloseHandle
```

### フローチャート

```mermaid
flowchart TD
    A[ConptyCreatePseudoConsole] --> B[入力検証]
    B --> C[PseudoConsole構造体をHeapAlloc]
    C --> D[入出力ハンドルを複製]
    D --> E[_CreatePseudoConsole]
    E --> F[サーバーハンドル作成]
    F --> G[リファレンスハンドル作成]
    G --> H[シグナルパイプ作成]
    H --> I[conhost.exeコマンドライン構築]
    I --> J[CreateProcessAsUserW]
    J --> K[HPCONを返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-104-1 | サイズ検証 | X=0またはY=0の場合はE_INVALIDARG | 作成・リサイズ時 |
| BR-104-2 | ハンドル検証 | hInputとhOutputの両方が無効な場合はE_INVALIDARG | 作成時 |
| BR-104-3 | トークン正規化 | hToken=INVALID_HANDLE_VALUEの場合はnullptrに変換 | 作成時 |
| BR-104-4 | 継承設定 | シグナルパイプとサーバーハンドルのみがconhostに継承される | 作成時 |

### 計算ロジック

特殊な計算ロジックはない。

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E_INVALIDARG | 引数不正 | phPCがnull、サイズが0、ハンドルが無効 | HRESULTを返却 |
| NTSTATUS失敗 | ハンドル作成失敗 | CreateServerHandle/CreateClientHandle失敗 | HRESULTを返却 |
| Win32エラー | プロセス作成失敗 | CreateProcessAsUserW失敗 | HRESULTを返却 |

### リトライ仕様

リトライは不要。失敗時は呼び出し元が再試行を判断する。

## トランザクション仕様

scope_exitパターンにより、途中で失敗した場合は確保したリソース(ハンドル、メモリ)が自動的に解放される。

## パフォーマンス要件

- ConPTY作成はプロセス起動を伴うため、数百ミリ秒程度のレイテンシが発生する
- シグナルパイプ操作(リサイズ等)は軽量(WriteFile1回)

## セキュリティ考慮事項

- CreateProcessAsUserWでユーザートークンを指定可能であり、権限の低いコンテキストでのプロセス起動が可能
- ハンドル継承はPROC_THREAD_ATTRIBUTE_HANDLE_LISTで明示的に制限

## 備考

- OpenConsole.exeが同一ディレクトリに存在する場合はそちらを優先使用、なければconhost.exeにフォールバック
- WOW64環境ではファイルシステムリダイレクション無効化が必要(BUILD_WOW6432)
- ConptyPackPseudoConsoleは、外部からのPTYセッション（Terminal側から受信したハンドル）をHPCONにパッキングする

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | winconpty.h | `src/winconpty/winconpty.h` | PseudoConsole構造体(11-41行目)、シグナル定数(46-49行目) |

**読解のコツ**: PseudoConsole構造体の3つのハンドル(hSignal, hPtyReference, hConPtyProcess)の役割をコメントから理解すること。

#### Step 2: 作成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | winconpty.cpp | `src/winconpty/winconpty.cpp` | _CreatePseudoConsole(96-248行目) |

**主要処理フロー**:
1. **118-127行目**: サーバーハンドルとリファレンスハンドルの作成
2. **138-139行目**: シグナルパイプの作成
3. **160-174行目**: conhost.exeのコマンドライン構築
4. **229-241行目**: CreateProcessAsUserWでconhostを起動

#### Step 3: 各操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | winconpty.cpp | `src/winconpty/winconpty.cpp` | Resize(258-272行目)、ShowHide(305-317行目)、Reparent(331-354行目)、Close(365-385行目) |

### プログラム呼び出し階層図

```
ConptyCreatePseudoConsole (公開API)
    |
    +-- ConptyCreatePseudoConsoleAsUser
    |       +-- DuplicateHandle (入出力ハンドル複製)
    |       +-- _CreatePseudoConsole
    |           +-- CreateServerHandle
    |           +-- CreateClientHandle
    |           +-- CreatePipe (シグナルパイプ)
    |           +-- CreateProcessAsUserW (conhost.exe起動)
    |
ConptyResizePseudoConsole -> _ResizePseudoConsole -> WriteFile(シグナルパイプ)
ConptyClearPseudoConsole  -> _ClearPseudoConsole  -> WriteFile(シグナルパイプ)
ConptyClosePseudoConsole  -> _ClosePseudoConsole  -> _ClosePseudoConsoleMembers + HeapFree
```

### データフロー図

```
[入力]                           [処理]                          [出力]

ターミナルアプリ -----hInput---> ConPTY(conhost.exe) ----VT----> シェルプロセス
                                     |                              |
ターミナルアプリ <---hOutput---- ConPTY(conhost.exe) <---VT----- シェルプロセス
                                     |
シグナルパイプ ----(リサイズ等)--> ConPTY内部処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| winconpty.h | `src/winconpty/winconpty.h` | ソース(ヘッダ) | PseudoConsole構造体とAPI宣言 |
| winconpty.cpp | `src/winconpty/winconpty.cpp` | ソース(実装) | ConPTY APIの実装全体 |
| device.h | `src/winconpty/device.h` | ソース(ヘッダ) | ConDrvデバイスハンドル作成 |
| ConPtyTests.cpp | `src/winconpty/ft_pty/ConPtyTests.cpp` | テスト | ConPTY機能テスト |
