cpp_quote("#include ") #pragma region Desktop Family cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)") import "oaidl.idl"; import "ocidl.idl"; interface IJsDebug; interface IJsDebugProcess; interface IJsDebugStackWalker; interface IJsDebugDataTarget; interface IJsDebugEventCallback; interface IJsDebugFrame; interface IJsDebugProperty; interface IJsEnumDebugProperty; interface IJsDebugBreakPoint; cpp_quote("#define FACILITY_JsDEBUG 0xdc7") cpp_quote("// The Js runtime and the Js diag do not match.") cpp_quote("#define E_JsDEBUG_MISMATCHED_RUNTIME MAKE_HRESULT(1, FACILITY_JsDEBUG, 0x1)") cpp_quote("// Thread is not known to have any JS code, and will have no frames.") cpp_quote("#define E_JsDEBUG_UNKNOWN_THREAD MAKE_HRESULT(1, FACILITY_JsDEBUG, 0x2)") cpp_quote("// Frame is outside of the interpreter. For example, portions of the Js dll which are") cpp_quote("// logically not part of the interpreter.") cpp_quote("#define E_JsDEBUG_OUTSIDE_OF_VM MAKE_HRESULT(1, FACILITY_JsDEBUG, 0x4)") cpp_quote("// Specified memory address could not be written/read from") cpp_quote("#define E_JsDEBUG_INVALID_MEMORY_ADDRESS MAKE_HRESULT(1, FACILITY_JsDEBUG, 0x5)") cpp_quote("// No source location found to bind the breakpoint") cpp_quote("#define E_JsDEBUG_SOURCE_LOCATION_NOT_FOUND MAKE_HRESULT(1, FACILITY_JsDEBUG, 0x6)") cpp_quote("// Runtime not in debug mode") cpp_quote("#define E_JsDEBUG_RUNTIME_NOT_IN_DEBUG_MODE MAKE_HRESULT(1, FACILITY_JsDEBUG, 0x7)") #ifndef MIDL_PASS #define CONST const #else #define CONST #endif // Entry point interface into the Js debugging API. [ local, object, uuid(BE0E89DA-2AC5-4C04-AC5E-59956AAE3613), pointer_default(unique) ] interface IJsDebug: IUnknown { // Factory method used to create a new virtual process object. // // ProcessId: Process Id to attach the debugger to. // RuntimeJsBaseAddress: The base address at which the Js runtime has loaded into the // target process. // pDataTarget: Debugger supplied interface to query for state of the process. // ppProcess: New debug process object // // Error conditions: // E_JsDEBUG_MISMATCHED_RUNTIME if Jscript9diag and Jscript9 do not match. HRESULT OpenVirtualProcess( [in] DWORD processId, [in] UINT64 runtimeJsBaseAddress, [in] IJsDebugDataTarget* pDataTarget, [out] IJsDebugProcess** ppProcess ); }; // Provides routines for inspecting/controlling the target process [ local, object, uuid(3D587168-6A2D-4041-BD3B-0DE674502862), pointer_default(unique) ] interface IJsDebugProcess: IUnknown { // Factory method for stack walker. This may fail with // E_JsDEBUG_UNKNOWN_THREAD if the thread does not have javascript on it // This method may only be called while the target process is stopped. HRESULT CreateStackWalker( [in] DWORD threadId, [out] IJsDebugStackWalker** ppStackWalker); // Sets the breakpoint at the specified document position // documentId: Pointer to IDebugDocumentText // characterOffset: Character offset from the beginning of the file. // characterCount: Length of the document text within which the breakpoint should be inserted // ppDebugbreakPoint: Object representing the breakpoint that got created. HRESULT CreateBreakPoint( [in] UINT64 documentId, [in] DWORD characterOffset, [in] DWORD characterCount, [in] BOOL isEnabled, [out] IJsDebugBreakPoint** ppDebugBreakPoint); // Puts the script engine in break mode causing it to // break on the next script instruction. HRESULT PerformAsyncBreak( [in] DWORD threadId); // Gets a code address close to external projection function call. HRESULT GetExternalStepAddress( [out] UINT64 *pCodeAddress); }; // Stack walker for a particular thread. Stack walkers can only be created // while the target is stopped, and are invalid once the target process has been // continued again. [ local, object, uuid(DB24B094-73C4-456C-A4EC-E90EA00BDFE3), pointer_default(unique) ] interface IJsDebugStackWalker: IUnknown { // Gets the next frame // Error conditions: // E_JsDEBUG_OUTSIDE_OF_VM : When there are no more stack frames to be enumerated HRESULT GetNext( [out] IJsDebugFrame** ppFrame); }; // Object represeting a stack frame [ local, object, uuid(C9196637-AB9D-44B2-BAD2-13B95B3F390E), pointer_default(unique) ] interface IJsDebugFrame: IUnknown { // Returns the absolute address range of the logical javascript stack frame. (This is useful for piecing together interleaved stack // traces gathered from multiple runtimes. ) The start of a stack range is the bottom most stack pointer of the frame, and // the end of a stack range is the top most stack pointer of the frame. // The start > end as the stack grows from high to low address. The start, end stack pointers can encompass // multiple physical machine stack frames (for interpreted javascript runtime frames) HRESULT GetStackRange( [out] UINT64 *pStart, [out] UINT64 *pEnd); // Get the user-friendly name of stack frame. HRESULT GetName( [out] BSTR* pName); // Returns the current position of this stack frame within the user-level document. // pDocumentId: Unique ID for a source document (pointer to the IDebugDocumentText) // pCharacterOffset: The zero-based character offset from the start of the script. // pStatementCharCount: the length of current statement, which starts at *pCharacterOffset, in characters. HRESULT GetDocumentPositionWithId( [out] UINT64* pDocumentId, [out] DWORD* pCharacterOffset, [out] DWORD* pStatementCharCount); // Returns the current position of this stack frame within the user-level document. // pDocumentName: For static scripts, a URL to document. For dynamic scripts, a buffer is returned. // pLine: 1-based line position within the document // pColumn: 1-based line position within the document HRESULT GetDocumentPositionWithName( [out] BSTR* pDocumentName, [out] DWORD* pLine, [out] DWORD* pColumn); // Returns a property browser for this stack frame. HRESULT GetDebugProperty( [out] IJsDebugProperty** ppDebugProperty); // Returns the return address pushed at the 'start' (see GetStackRange) of the frame HRESULT GetReturnAddress( [out] UINT64 *pReturnAddress); // Evaluate an expression in the context of this stack frame. Returns: // S_OK: Evaluation succeeds, *ppDebugProperty contains evaluation result. // S_FALSE: Evaluation throws an error (or possibly involved evaluation operation not supported), *pError contains error message. HRESULT Evaluate( [in] LPCOLESTR pExpressionText, [out] IJsDebugProperty** ppDebugProperty, [out] BSTR* pError); }; typedef enum JS_PROPERTY_MEMBERS { JS_PROPERTY_MEMBERS_ALL = 0, JS_PROPERTY_MEMBERS_ARGUMENTS = 1, } JS_PROPERTY_MEMBERS; [v1_enum] typedef enum JS_PROPERTY_ATTRIBUTES { JS_PROPERTY_ATTRIBUTE_NONE = 0, JS_PROPERTY_HAS_CHILDREN = 0x1, JS_PROPERTY_FAKE = 0x2, JS_PROPERTY_METHOD = 0x4, JS_PROPERTY_READONLY = 0x8, JS_PROPERTY_NATIVE_WINRT_POINTER = 0x10, JS_PROPERTY_FRAME_INTRYBLOCK = 0x20, // this frame is in a try block JS_PROPERTY_FRAME_INCATCHBLOCK = 0x40, // this frame is in a catch block JS_PROPERTY_FRAME_INFINALLYBLOCK = 0x80, // this frame is in a finally block } JS_PROPERTY_ATTRIBUTES; typedef struct tagJsDebugPropertyInfo { BSTR name; BSTR type; BSTR value; BSTR fullName; JS_PROPERTY_ATTRIBUTES attr; } JsDebugPropertyInfo; // IJsDebugProperty [ local, object, uuid(F8FFCF2B-3AA4-4320-85C3-52A312BA9633), pointer_default(unique) ] interface IJsDebugProperty : IUnknown { // Get Information for this object HRESULT GetPropertyInfo( [in] UINT nRadix, [out] JsDebugPropertyInfo* pPropertyInfo); // Get members HRESULT GetMembers( [in] JS_PROPERTY_MEMBERS members, [out] IJsEnumDebugProperty** ppEnum); }; // IJsEnumDebugProperty [ local, object, uuid(4092432F-2F0F-4FE1-B638-5B74A52CDCBE), pointer_default(unique) ] interface IJsEnumDebugProperty : IUnknown { // Read properties HRESULT Next( [in] ULONG count, [out, size_is(count), length_is(*pActualCount)] IJsDebugProperty** ppDebugProperty, [out] ULONG* pActualCount); // Get total count of properties HRESULT GetCount( [out] ULONG* pCount); }; // Interface representing a breakpoint [ local, object, uuid(DF6773E3-ED8D-488B-8A3E-5812577D1542), pointer_default(unique) ] interface IJsDebugBreakPoint: IUnknown { // Determines if the breakpoint is enabled. // Returns E_UNEXPECTED if called on a deleted breakpoint. HRESULT IsEnabled([out] BOOL* pIsEnabled); // Enables the breakpoint // Returns E_UNEXPECTED if called on a deleted breakpoint. // Returns S_FALSE if called on an already enabled breapoint. HRESULT Enable(); // Disables the breakpoint // Returns E_UNEXPECTED if called on a deleted breakpoint. // Returns S_FALSE if called on an already disabled breapoint. HRESULT Disable(); // Deletes the breakpoint // Returns S_FALSE if called on a deleted breakpoint. HRESULT Delete(); // Returns the position of the statement where the breakpoint was bound. // pDocumentId: Unique ID for a source document (pointer to the IDebugDocumentText) // pCharacterOffset: The zero-based character offset from the start of the script. // pStatementCharCount: the length of current statement, which starts at *pCharacterOffset, in characters. HRESULT GetDocumentPosition( [out] UINT64* pDocumentId, [out] DWORD* pCharacterOffset, [out] DWORD* pStatementCharCount); } // Represents a stack frame. // Used by IJsStackFrameEnumerator. typedef struct { UINT64 InstructionOffset; UINT64 ReturnOffset; UINT64 FrameOffset; UINT64 StackOffset; } JS_NATIVE_FRAME; // Implemented by debugger to provide stack unwinding support to jscript9diag. [ local, object, uuid(5E7DA34B-FB51-4791-ABE7-CB5BDF419755), pointer_default(unique) ] interface IEnumJsStackFrames: IUnknown { // Retrieves next cFrameCount frames into array provided by the caller. HRESULT Next( [in] ULONG cFrameCount, [out, size_is(cFrameCount), length_is(*pcFetched)] JS_NATIVE_FRAME* pFrames, [out] ULONG * pcFetched); // Reset to position before 1st element. HRESULT Reset(void); } [v1_enum] typedef enum JsDebugReadMemoryFlags { // Indicates that the caller wants the default behavior for ReadMemory. None = 0x0, // Indicates that the caller wants the read operation to succeed if only part of // the memory read succeeded. If this is set, an E_JsDEBUG_INVALID_MEMORY_ADDRESS error // will only be raised if 'Address' is invalid. If this flag is clear, a // E_JsDEBUG_INVALID_MEMORY_ADDRESS error will be raised if any portion of the requested // memory was unreadable. JsDebugAllowPartialRead = 0x1 } JsDebugReadMemoryFlags; [ local, object, uuid(53B28977-53A1-48E5-9000-5D0DFA893931), pointer_default(unique) ] interface IJsDebugDataTarget: IUnknown { // Read the memory of the target process. // Address : [In] The base address from which to read the target process's // memory. // Flags : [In] Flags controlling the behavior of ReadMemory // pBuffer : [In,Out] A buffer that receives the contents from the address // space of the target process. On failure, the content of this buffer is // unspecified. // Size : [In] The number of bytes to be read from the process. // pBytesRead : [Out] Indicates the number of bytes read from the // target process. If JsDebugAllowPartialRead is clear, on success this // value will always be exactly equal to the input size. If // JsDebugAllowPartialRead is specified, on success, this value will be // greater than zero. // Return value : S_OK is returned on success, and failure codes are used for any // error. E_JsDEBUG_INVALID_MEMORY_ADDRESS indicates that the address is not valid. See // 'JsDebugAllowPartialRead' documentation for more information. HRESULT ReadMemory( [in] UINT64 address, [in] JsDebugReadMemoryFlags flags, [out, size_is(size), length_is(*pBytesRead)] BYTE* pBuffer, [in] DWORD size, [out] DWORD* pBytesRead); // Writes memory to the target process. Before data transfer occurs, the system // verifies that all data in the base address and memory of the specified size is // accessible for write access, and if it is not accessible, the function raises an // E_JsDEBUG_INVALID_MEMORY_ADDRESS error. // address : [In] The base address from which to write the target process's memory. // pMemory : [In] Data to be written in the address space of the specified process. HRESULT WriteMemory( [in] UINT64 address, [in, size_is(size)] CONST BYTE* pMemory, [in] DWORD size); // Reserves and/or commits a region of memory within the virtual address space of the // target process. The function initializes the memory it allocates to zero, unless // MEM_RESET is used. For additional information, see the VirtualAlloc Win32 API in // MSDN. // address : [In] Address within the target process where the memory should // be committed or reserved. This value is typically zero, in which case the system // chooses an address. // size : [In] The size of the region of memory to allocate, in bytes. The // system will automatically round up to the next page boundary. // allocationType : [In] Indicates the type of allocation to perform. This is // typically MEM_COMMIT | MEM_RESERVE (0x3000) which reserves and commits an // allocation in one step. // pageProtection : [In] The memory protection for the region of pages to be // allocated. If the pages are being committed, you can specify any one of the memory // protection constants (ex: PAGE_READWRITE, PAGE_EXECUTE). // pAllocatedAddress: [Out] Base address of the allocated region of pages. HRESULT AllocateVirtualMemory( [in] UINT64 address, [in] DWORD size, [in] DWORD allocationType, [in] DWORD pageProtection, [out] UINT64* pAllocatedAddress); // Releases and/or decommits a region of memory within the virtual address space of // the target process. For additional information, see the VirtualFree Win32 API in // MSDN. // address : [In] Address within the target process where the memory should // be freed. // size : [In] Number of bytes to decommit. To release a region of memory, // this value must be zero. // freeType : [In] Indicates the type of free operation to perform. This is // typically MEM_RELEASE (0x8000), which releases the specified region of pages. // After the operation, the pages are in the free state. MEM_DECOMMIT (0x4000) can be // used instead to decommit the pages without releasing them. HRESULT FreeVirtualMemory( [in] UINT64 address, [in] DWORD size, [in] DWORD freeType); // Retrieves the value in the debuggee thread's thread local storage (TLS) slot for // the specified TLS index. Each thread of a process has its own slot for each TLS // index. // threadId : [In] Thread running in the target process to read from // tlsIndex : [In] The TLS index that was allocated when the target process // called the TlsAlloc function. // pValue : [Out] The pointer-sized value which was stored in the thread's // TLS slot. If the target thread is 32-bit, the upper 32-bits of this value will be // zero. HRESULT GetTlsValue( [in] DWORD threadId, [in] UINT32 tlsIndex, [out] UINT64* pValue ); // Reads a BSTR from the debug target // E_JsDEBUG_INVALID_MEMORY_ADDRESS indicates that the address is not valid. HRESULT ReadBSTR( [in] UINT64 address, [out] BSTR* pString ); // Read at most maxCharacters from the target. // characerSize: size of each character in the string // maxCharacters should be reasonable. Any request for more than 128MB of memory will fail. If the string is larger than // maxCharacters, the result string will be truncated after maxCharacters. // Returns S_FALSE if truncated // E_JsDEBUG_INVALID_MEMORY_ADDRESS indicates that the address is not valid. HRESULT ReadNullTerminatedString( [in] UINT64 address, [in] UINT16 characterSize, [in] UINT32 maxCharacters, [out] BSTR* pString ); // Creates enumerator for stack frames HRESULT CreateStackFrameEnumerator( [in] DWORD threadId, [out] IEnumJsStackFrames** ppEnumerator); // Retrieves context for given thread. // Used by JS on x86/amd64 to get initial top frame base offset. HRESULT GetThreadContext( [in] DWORD threadId, // This is same as the ContextFlags field of CONTEXT (see winnt.h, search for CONTEXT_ALL). [in] ULONG32 contextFlags, // The size of the buffer specified by pContext. [in] ULONG32 contextSize, // Receives platform-specific CONTEXT structure into buffer specified by pContext. [out, size_is(contextSize)] void* pContext); }; cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */") #pragma endregion