22 November, 2012

Visual Studio project type GUIDs

I updated the original table.

Project Language Project Type Guid
C# {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
F# {F2A71F9B-5D33-465A-A702-920D77279786}
J# {E6FDF86B-F3D1-11D4-8576-0002A516ECE8}
VB.NET {F184B08F-C81C-45F6-A57F-5ABD9991F28F}
C++ {8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}

Project Type Description Project Type Guid
Web Application {349C5851-65DF-11DA-9384-00065B846F21}
Web Site {E24C65DC-7377-472B-9ABA-BC803B73C61A}
Distributed System {F135691A-BF7E-435D-8960-F99683D2D49C}
Windows Communication Foundation (WCF) {3D9AD99F-2412-4246-B90B-4EAA41C64699}
Windows Presentation Foundation (WPF) {60DC8134-EBA5-43B8-BCC9-BB4BC16C2548}
Visual Database Tools {C252FEB5-A946-4202-B1D4-9916A0590387}
Database {A9ACE9BB-CECE-4E62-9AA4-C7E7C5BD2124}
Database (other project types) {4F174C21-8C12-11D0-8340-0000F80270F8}
Test {3AC096D0-A1C2-E12C-1390-A8335801FDAB}
Legacy (2003) Smart Device (C#) {20D4826A-C6FA-45DB-90F4-C717570B9F32}
Legacy (2003) Smart Device (VB.NET) {CB4CE8C6-1BDB-4DC7-A4D3-65A1999772F8}
Smart Device (C#) {4D628B5B-2FBC-4AA6-8C16-197242AEB884}
Smart Device (VB.NET) {68B1623D-7FB9-47D8-8664-7ECEA3297D4F}
Workflow Foundation {32F31D43-81CC-4C15-9DE6-3FC5453562B6}
Workflow (C#) {14822709-B5A1-4724-98CA-57A101D1B079}
Workflow (VB.NET) {D59BE175-2ED0-4C54-BE3D-CDAA9F3214C8}
Deployment Merge Module {06A35CCD-C46D-44D5-987B-CF40FF872267}
Deployment Cab {3EA9E505-35AC-4774-B492-AD1749C4943A}
Deployment Setup {978C614F-708E-4E1A-B201-565925725DBA}
Deployment Smart Device Cab {AB322303-2255-48EF-A496-5904EB18DA55}
Visual Studio Tools for Applications (VSTA) {A860303F-1F3F-4691-B57E-529FC101A107}
Visual Studio Tools for Office (VSTO) {BAA0C2D2-18E2-41B9-852F-F413020CAA33}
SharePoint Workflow {F8810EC1-6754-47FC-A15F-DFABD2E3FA90}
SharePoint (VB.NET) {EC05E597-79D4-47f3-ADA0-324C4F7C7484}
SharePoint (C#) {593B0543-81F6-4436-BA1E-4747859CAAE2}
XNA (Windows) {6D335F3A-9D43-41b4-9D22-F6F17C4BE596}
XNA (XBox) {2DF5C3F4-5A5F-47a9-8E94-23B4456F55E2}
XNA (Zune) {D399B71A-8929-442a-A9AC-8BEC78BB2433}
Silverlight {A1591282-1198-4647-A2B1-27E5FF5F6F3B}
Model-View-Controller v2 (MVC2) {F85E285D-A4E0-4152-9332-AB1D724D3325}
Model-View-Controller v3 (MVC3) {E53F8FEA-EAE0-44A6-8774-FFD645390401}
Model-View-Controller v4 (MVC4) {E3E379DF-F4C6-4180-9B81-6769533ABE47}
Windows Store Apps (Metro Apps) {BC8A1FFA-BEE3-4634-8014-F334798102B3}

10 November, 2012

SyntaxHighlighter brushes for WinDbg disassembler output

I spent a lot of time looking for SyntaxHighlighter brush for disassembler output. Unfortunately, I didn't find a good one. So, today I have to write my own brushes for it:

22 October, 2012

How to get x64 dynamic function table critical section?

There is the standard way to walk on stack under Windows x64: RtlLookupFunctionEntry() and RtlVirtualUnwind() API calls. These methods use additional information to unwind stack: static and dynamic function tables. Static tables are generated by compilers and stored insight DLLs. Dynamic ones generated by application (CLR in fact is part of application) for dynamically created methods.

How RegSvr32 works on x64?

File system redirection works in x64 OS. It means that when you are 32-bits application and try to run %WinDir%\System32\RegSvr32.exe, you run %WinDir%\SysWOW64\RegSvr32.exe in fact. It's very good for compatibility. However, there is the problem when you want to register 64-bits COM DLL from 32-bits process: 32-bits process can't work with 64-bits DLL.

RegSvr32 do the special work to solve this problem. It detects that it works in WOW64 mode and DLL is 64-bit then ... it disable file system redirection for current thread by the Wow64EnableWow64FsRedirection() call and run itself (the command line contains original path: %WinDir%\System32\RegSvr32.exe) with the same arguments. Ta-da... It's beautiful decision!

Update: However, run itself in 64-bits mode will be skipped when 32-bits application loads 64-bits DLL by LoadLibraryEx() call and get the non-right error code - only the ERROR_BAD_EXE_FORMAT (0xC1) error code is expected.

12 October, 2012

WinRT local network isolation

By default only VS2012 deployed applications have the localhost network isolation in disabled state. All other application can't connect to localhost. There are at least two tools to control which application can connect to localhost which not: CheckNetIsolation and EnableLoopback. Here is the way how to do it from you own program:

21 September, 2012

Identifiers in ETW and Profiling API

CLR v4.0/v4.5 can generate ETW CLR events. There is special section and for operations relating to loading and unloading application domains, assemblies, and modules. This article contains a lot of identifiers such as AppDomainID, AssemblyID, ModuleID. Descriptions of them sometimes contains word "unique". This word is parasite. All identifiers are unique, but unique only during object life. It means that it possible to have two and more different objects with the same identifier, but in different moments of an application life.

17 August, 2012

Windows Store feature

Your Windows Store application will be automatically registered if you compile it under Visual Studio 2012 and run/debug. However, get_InstalledLocation() method of ABI::Windows::ApplicationModel::IPackage interface will return error if you press Clean Build in Visual Studio.

27 June, 2012

How to detect is UAC enabled or not?

There are at least three ways to detect UAC (User Access Control) is active or not:

  • Check the registry value EnableLUA at HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System. However, there is the one problem: the value can be changed at any time, but it won't be used by OS until the computer reboot. So, this way is possible, but it isn't good.
  • Call GetTokenInformation() with TokenElevationType and TokenElevation. It doesn't work in all situations. It's impossible to detect UAC when an application runs under conventional user (TokenElevationType returns TokenElevationTypeDefault and TokenElevation returns FALSE).
  • Call private API method (valid only for Windows Vista and later):
    #pragma comment(lib, "ntdll.lib")
    
    #define ELEVATION_UAC_ENABLED                 0x1
    #define ELEVATION_VIRTUALIZATION_ENABLED      0x2
    #define ELEVATION_INSTALLER_DETECTION_ENABLED 0x4
    
    extern "C"
    NTSTATUS
    NTAPI
    RtlQueryElevationFlags(
            DWORD* pFlags);
    
    Unfortunately, there is no declaration of this method in Windows Driver Kit (WDK), but ntdll.lib from WDK contains it.

24 June, 2012

This blog change the language today

Hi everybody. Today I decided to change the language of this blog. So, next messages will be in English. I promise to translate old messages from Russian to English in future.

23 June, 2012

Запуск non-elevated процесса из под elevated

Неожиданно возникла проблема, что некоторые API в Windows 8 работают только из под non-elevated пользователя и только когда UAC включен. Соответственно встал вопрос как прикинуться non-elevated пользователем, если программа запущена под elevated пользователем. Сразу скажу, мы не знаем пользователький пароль.

12 June, 2012

Репортаж из песочницы

S-1-15-2-1 (ALL_APP_PACKAGES) - это магический SID позволяет достучатся к любому файлу или каталогу из WinRT песочницы.

Update: Этот же SID помогает установить соединение через named pipe из песочницы наружу.

Update: Этот же SID помогает достучаться до реестра.

28 April, 2012

Stack walker для CLR x64

Сразу оговорюсь, что в принципе можно не использовать DoStackSnapshot() вообще для платформы x64 так как в наличии есть RtlLookupFunctionEntry() и RtlVirtualUnwind(). Но, я бы не рекомендовал так делать (хотя некоторые могут со мной не согласиться), потому что во время вызова DoStackSnapshot() происходят дополнительные проверки и синхронизации, которые вы не сможете сделать другими средствами. А как же GetFunctionFromIP() скажете вы? Отвечаю, что это очень простой по устройству метод, который просто не делает весь спектр необходимых проверок.

28 January, 2012

Сюрприз Profiling API

На днях, при отладке профайлера, на приложении выделяющим и инициализирующим массив в 2Gb (максимальный размер объекта в CLR), во время очередного GC, был замечен странный кратковременный всплеск потребления памяти - выделялось дополнительно еще 2Gb (итого пиково было 4Gb). После расследования выяснилось, что на время вызова ICorProfilerCallback::ObjectReferences() CLR выделяет массив для передачи в профайлер всех исходящих рефернсов соответствующего объекта. Если референсы занимают эти самые 2Gb, то будут выделен массив в 2Gb. Проблема возникает только тогда, когда ICorProfilerCallback::ObjectReferences() возвращает всегда S_OK и производится полный обход графа для профайлера.

Собственно приложение (число 9 в коде подобрано для CLR 4.0 x64):

using System;

namespace AllocationTest
{
  internal class Program
  {
    private static void Main()
    {
      var tmp = new object[0x80000000U / (uint) IntPtr.Size - 9];

      for (int n = 0; n < tmp.Length; ++n)
        tmp[n] = tmp;

      Console.Write("Press any key...");
      Console.ReadKey();
      Console.WriteLine();

      GC.KeepAlive(tmp);
    }
  }
}
P.S. Если убрать в примере запонение массива, то эффект наблюдается не будет.
P.P.S.CLR v4.5 x64 может выделять массивы больше чем 2Gb! Смотри gcAllowVeryLargeObjects.